library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(loo) # for information criteria
library(tidybayes) # Bayesian aesthetics
library(MetBrewer) # colours
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(pander) # for simpler tables
library(png) # to load images
library(grid) # to plot images
library(ggdag) # to draw dags

Load in the data

We analyse data collected across three cohorts of students (2021-2023) enrolled in the third year School of Biosciences subject, Animal Behaviour, at The University of Melbourne. We hereafter refer to students as observers.

data <- read_csv("data/pigeon_data.csv") %>% 
  mutate(Student_ID = as.factor(Student_ID),
         Year = as.factor(Year),
         Foraging_prop = (Foraging_percentage / 100)) %>%
  filter(Year %in% c("2021", "2022", "2023"),
         Foraging_percentage != "NA",
         Primer_understood != "NA") %>%
  filter(Student_ID != "60" & Student_ID != "68" & Student_ID != "70" & Student_ID != "72") %>% # remove students that completed the task multiple times
  #Student_ID %in% c("60", "68", "70", "72")) %>% 
  select(-c(First_name, Surname, Peck_mean)) %>%  # remove names when ready
  left_join(
    read_csv("data/gender_data.csv") %>% 
      mutate(Student_ID = as.factor(Student_ID))
  ) %>% 
  rename(Observer_ID = Student_ID) %>% 
  select(Observer_ID, Year, Gender, everything())

data_peck <- 
  data %>%
  filter(Peck_rate_2 != "NA") %>% 
  pivot_longer(cols = Peck_rate_1:Peck_rate_2, names_to = "Trial",
               values_to = "Peck_rate")
  
# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'full_dataset')),
      pageLength = 78
    )
  )
}


my_data_table(data)

Column explanations

Observer_ID: unique, anonymised identifier for each observer.

Year: year that the experiment was conducted.

Gender: upon enrollment at The University of Melbourne, students are asked to indicate their title. We identified women as observers that answered “Miss” or “Ms” and Men as those who that answered “Mr”. Those with entirely missing entries were coded as “NA”.

Bias_treatment: the primer the observer received, where ‘satiated’ indicates that the observers were provided information prior to a trial that suggested pigeons were fell fed, whereas ‘hungry’ indicated that the pigeons were in poor condition and hungry.

Expectation: we asked the observers to indicate whether they thought the pigeons would be hungry or satiated. We included this question to test whether observers were appropriately primed by their bias treatment.

Primer_understood: did the observer’s expectation match the primer they received?

Foraging_percentage: the percentage of pigeons that observers estimated to be foraging over a 15 second period, while observing a large flock.

Peck_rate_1: the number of times a single chosen pigeon pecked the ground over a 15 second period.

Peck_rate_2: the number of times a second chosen pigeon pecked the ground over a 15 second period.

Foraging_prop: proportion of pigeons estimated to be foraging

\(~\)

Question 1: is estimation of foraging percentage affected by bias manipulations?

\(~\)

Exploring allocation versus expectation 1

\(~\)

We find that 22 of the 78 observers indicated a feeding motivation expectation opposite to that implied by the primer they were allocated.

This suggests that Expectation may be a better predictor of foraging estimation than allocated Bias_treatment. The relationship between these and all other variables that we expect to play a role in this system are depicted in Figure 1.

We explicitly assess the effect of treatment and expectation by fitting two models:

  1. a model with allocated primer (Bias_treatment) as the predictor variable

  2. a model with indicated hunger expectation (Expectation) as the predictor variable

\(~\)

gg_simple_dag <- function(d) {
  d %>% 
    ggplot(aes(x = x, y = y, xend = xend, yend = yend, colour = Variables)) +
    geom_dag_point() +
    scale_colour_manual(values = c("Included in model" = met.brewer("Hiroshige")[4], "Not included in model" = "grey80")) +
    geom_dag_text(color = met.brewer("Hiroshige")[7]) +
    geom_dag_edges() + 
    theme_dag()+
    theme(legend.position = "bottom",
          legend.title = element_blank())
}


observer_bias_dag <- dagify(EF ~ PEW + PEM + SB + TF,
        PEW ~ BT,
        PEM ~ BT,
        SB ~ PEW + PEM,
       labels = c("TF" = "True\n Foraging", 
                  "EF" = "Estimated\n Foraging",
                  "PEW" = "Prior\n Expectation Men",
                  "PEM" = "Prior\n Expectation Women",
                  "BT" = "Bias\n Treatment",
                  "SB" = "Selection\n Bias")) %>% 
  tidy_dagitty(seed = 5)
  
  
 observer_bias_dag <- left_join(observer_bias_dag$data, tibble(name = c("BT", "EF", "PEW", "PEM", "SB", "TF"),
                                   Variables = c("Included in model", "Included in model", "Included in model", "Included in model", "Not included in model", "Not included in model"))) %>% 
   
 gg_simple_dag()


observer_bias_dag

Figure 1. A direct acrylic diagram showing the flow of causation in our biological system. Our bias treatment (BT) was designed to affect the prior expectation (PE) of observer’s, a subset of which were women (PEW), while the remaining were men (PEM). Prior expectations may affect the estimated level of foraging (EF) directly, or more specifically through biased selection of particular foragers (SB). Estimated foraging is also affected by the true level of foraging (TF) carried out by the flock of pigeons in the footage. We hypothesised that a priori expectations of observer’s would affect their foraging estimates. The paths connecting coloured variables show that this can be tested by modelling the effect of bias treatment on estimated foraging, or alternatively by directly modelling the effect of prior expectation on estimated foraging.

\(~\)

Model 1: allocated primer

# First let's model the effect of bias treatment on foraging estimation 

foraging_model_treatment <- brm(Foraging_prop ~ 0 + Bias_treatment,
                                     data = data, family = Beta,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = phi)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.8, max_treedepth = 10),
                                     seed = 1, file = "fits/foraging_model_treatment")

foraging_model_treatment <- add_criterion(foraging_model_treatment, criterion = "loo", file = "fits/foraging_model_treatment")

foraging_model_treatment
##  Family: beta 
##   Links: mu = logit; phi = identity 
## Formula: Foraging_prop ~ 0 + Bias_treatment 
##    Data: data (Number of observations: 78) 
##   Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
##          total post-warmup draws = 16000
## 
## Population-Level Effects: 
##                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Bias_treatmentHungry      -0.47      0.14    -0.74    -0.20 1.00    14927
## Bias_treatmentSatiated    -0.47      0.15    -0.76    -0.17 1.00    14749
##                        Tail_ESS
## Bias_treatmentHungry      12186
## Bias_treatmentSatiated    11819
## 
## Family Specific Parameters: 
##     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## phi     4.21      0.61     3.11     5.48 1.00    13695    12202
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
foraging_model_treatment_gender <- brm(Foraging_prop ~ 0 + Gender * Bias_treatment,
                                     data = data, family = Beta,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = phi)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.8, max_treedepth = 10),
                                     seed = 1, file = "fits/foraging_model_treatment_gender")

Table S1. Posterior estimates of the percentage of pigeon feeding rate, split by the primer observers were allocated.

new_data <- tibble(Bias_treatment = c("Hungry", "Satiated"))

new_data %>% 
  left_join(data %>% group_by(Bias_treatment) %>% summarise(`n observers` = n())) %>% 
  cbind(fitted(foraging_model_treatment, newdata = new_data, summary = T) %>% 
          as_tibble() %>% 
          mutate(across(1:4, ~ .x *100),
                 across(1:4, round, 2))) %>% 
  rename("Estimated proportion foraging" = Estimate,
         "Bias treatment" = Bias_treatment) %>% 
  pander(split.cell = 20, split.table = Inf)
Bias treatment n observers Estimated proportion foraging Est.Error Q2.5 Q97.5
Hungry 42 38.47 3.25 32.24 44.99
Satiated 36 38.59 3.51 31.85 45.65

or the gender analysis version

# add gender predictions

new_data_gender <- expand_grid(Bias_treatment = c("Hungry", "Satiated"),
                               Gender = c("Woman", "Man"))

new_data_gender %>% 
  left_join(data %>% group_by(Gender, Bias_treatment) %>% summarise(`n observers` = n()) %>% 
          ungroup() %>% filter(!is.na(Gender))) %>% 
  cbind(fitted(foraging_model_treatment_gender, newdata = new_data_gender, summary = T) %>% 
          as_tibble() %>% 
          mutate(across(1:4, ~ .x *100),
                 across(1:4, round, 2))) %>% 
  rename("Estimated proportion foraging" = Estimate,
         "Bias treatment" = Bias_treatment) %>% 
  pander(split.cell = 20, split.table = Inf)
Bias treatment Gender n observers Estimated proportion foraging Est.Error Q2.5 Q97.5
Hungry Woman 30 40.34 3.86 32.91 48.1
Hungry Man 11 33.3 5.79 22.36 45.21
Satiated Woman 27 38.99 4.03 31.26 47.1
Satiated Man 9 36.94 6.68 24.27 50.4

Model 2: indicated expectation

# fit the same model, except using participant expectation rather than allocated bias treatment

foraging_model_expectation <- brm(Foraging_prop ~ 0 + Expectation,
                                     data = data, family = Beta,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = phi)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.8, max_treedepth = 10),
                                     seed = 1, file = "fits/foraging_model_expectation")

foraging_model_expectation <- add_criterion(foraging_model_expectation, criterion = "loo", file = "fits/foraging_model_expectation")

foraging_model_expectation
##  Family: beta 
##   Links: mu = logit; phi = identity 
## Formula: Foraging_prop ~ 0 + Expectation 
##    Data: data (Number of observations: 78) 
##   Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
##          total post-warmup draws = 16000
## 
## Population-Level Effects: 
##                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## ExpectationHungry      -0.40      0.13    -0.66    -0.14 1.00    15078    12139
## ExpectationSatiated    -0.56      0.15    -0.87    -0.26 1.00    15944    12233
## 
## Family Specific Parameters: 
##     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## phi     4.25      0.62     3.12     5.55 1.00    16348    12206
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
foraging_model_expectation_gender <- brm(Foraging_prop ~ 0 + Gender * Expectation,
                                     data = data, family = Beta,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = phi)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.8, max_treedepth = 10),
                                     seed = 1, file = "fits/foraging_model_expectation_gender")

Table S2. Posterior estimates of the percentage of pigeons foraging, split by the actual expectation of observers.

new_data_2 <- tibble(Expectation = c("Hungry", "Satiated"))

new_data_2 %>% 
   left_join(data %>% group_by(Expectation) %>% summarise(`n observers` = n())) %>% 
  cbind(fitted(foraging_model_expectation, newdata = new_data_2, summary = T) %>% 
          as_tibble() %>% 
          mutate(across(1:4, ~ .x *100),
                 across(1:4, round, 2))) %>%  
  rename("Estimated proportion foraging" = Estimate,
         "Indicated expectation" = Expectation) %>% 
  pander(split.cell = 20, split.table = Inf)
Indicated expectation n observers Estimated proportion foraging Est.Error Q2.5 Q97.5
Hungry 44 40.2 3.19 34.08 46.62
Satiated 34 36.38 3.56 29.61 43.56

the gender analysis version

# add gender predictions

new_data_gender_2 <- expand_grid(Expectation = c("Hungry", "Satiated"),
                               Gender = c("Woman", "Man"))

new_data_gender_2 %>% 
  left_join(data %>% group_by(Expectation, Gender) %>% summarise(`n observers` = n()) %>% 
          ungroup() %>% filter(!is.na(Gender))) %>%
  cbind(fitted(foraging_model_expectation_gender, 
               newdata = new_data_gender_2, summary = T) %>% 
          as_tibble() %>% 
          mutate(across(1:4, ~ .x *100),
                 across(1:4, round, 2))) %>% 
  rename("Estimated proportion foraging" = Estimate,
         "Indicated expectation" = Expectation) %>% 
  pander(split.cell = 20, split.table = Inf)
Indicated expectation Gender n observers Estimated proportion foraging Est.Error Q2.5 Q97.5
Hungry Woman 32 42.7 3.75 35.42 50.11
Hungry Man 12 34.41 5.58 23.91 45.81
Satiated Woman 25 35.94 4.12 28.17 44.2
Satiated Man 8 35.64 6.96 22.38 49.6

\(~\)

Build Figure 2a-d

\(~\)

Get posterior means and difference contrasts

# treatment model

draws_treatment <-
  as_draws_df(foraging_model_treatment) %>% 
  mutate(Hungry = inv_logit_scaled(b_Bias_treatmentHungry) *100,
         Satiated = inv_logit_scaled(b_Bias_treatmentSatiated)*100,
         diff_contrast = (Hungry - Satiated)) %>% 
  select(Hungry, Satiated, diff_contrast) %>% 
  pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>% 
  mutate(Predictor = "Allocated primer")

p2 <- 
  draws_treatment %>% 
  filter(Treatment != "diff_contrast") %>% 
  ggplot(aes(x = Treatment, y = Posterior_estimate)) + 
  stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) +
  scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip(ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Allocated primer") +
  ylab("Estimated % pigeons foraging") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 14))

p3 <-
  draws_treatment %>% 
  filter(Treatment == "diff_contrast") %>% 
  ggplot(aes(y = Posterior_estimate)) + 
   stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
  scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
  coord_flip(ylim = c(-20, 20)) +
  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab(NULL) +
  ylab("Hungry - Satiated difference\ncontrast (% points)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        text = element_text(size = 14))

# expectation model

draws_expectation <-
  as_draws_df(foraging_model_expectation) %>% 
  mutate(Hungry = inv_logit_scaled(b_ExpectationHungry) *100,
         Satiated = inv_logit_scaled(b_ExpectationSatiated)*100,
         diff_contrast = (Hungry - Satiated)) %>% 
  select(Hungry, Satiated, diff_contrast) %>% 
  pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>% 
  mutate(Predictor = "Indicated expectation")

p4 <-
  draws_expectation %>% 
  filter(Treatment != "diff_contrast") %>% 
  ggplot(aes(x = Treatment, y = Posterior_estimate)) + 
   stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) +
  scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip(ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Indicated expectation") +
  ylab("Estimated % pigeons foraging") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 14))

p5 <-
  draws_expectation %>% 
  filter(Treatment == "diff_contrast") %>% 
  ggplot(aes(y = Posterior_estimate)) + 
    stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
  scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
  coord_flip(ylim = c(-20, 20)) +
  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab(NULL) +
  ylab("Hungry - Satiated difference\ncontrast (% points)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        text = element_text(size = 14))

Now build the plots for the models that include gender

# treatment model

gender_treatment_draws <-
  fitted(foraging_model_treatment_gender, 
         newdata = new_data_gender, summary = F) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  pivot_longer(cols = 1:4, names_to = "Group", values_to = "Posterior_estimate") %>% 
  separate(sep = "_", col = Group, into = c("Treatment", "Gender")) %>%
  mutate(Posterior_estimate = Posterior_estimate*100) 
  
calculate_all_the_diffs <-
  fitted(foraging_model_treatment_gender, 
         newdata = new_data_gender, summary = F) %>% 
  as_tibble() %>% 
  rename(Hungry_Woman = V1, Hungry_Man = V2, Satiated_Woman = V3, Satiated_Man = V4) %>% 
  mutate(Woman_h_s_diff = Hungry_Woman - Satiated_Woman,
         Man_h_s_diff = Hungry_Man - Satiated_Man,
         diff_diff = Woman_h_s_diff - Man_h_s_diff) %>% 
  select(contains("diff")) %>%
  rename(`H-S (women)` = Woman_h_s_diff,
         `H-S (men)` = Man_h_s_diff,
         `Interaction` = diff_diff) %>% 
  pivot_longer(cols = 1:3, names_to = "diff_contrast", values_to = "posterior_diff") %>% 
  mutate(posterior_diff = posterior_diff*100)
  

gp1 <- 
  gender_treatment_draws %>% 
  ggplot(aes(x = Gender, y = Posterior_estimate)) + 
    stat_slab(alpha = 0.8, shape = 21, aes(fill = Treatment)) +
  #stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
   #            point_interval = "median_qi", point_fill = "white",
   #            shape = 21, point_size = 4, stroke = 1.5,
   #            fill = met.brewer("Hiroshige", 5)[2]) +
  #scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  scale_fill_manual(values = c(met.brewer("Hiroshige", 10)[4], met.brewer("Hiroshige", 10)[6])) +
  coord_flip()+#ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  labs(x = "Gender", y = "Estimated % pigeons foraging", fill = "Allocated\nprimer") +
  theme_bw() + 
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 10))



gp2 <-
  calculate_all_the_diffs %>% 
  ggplot(aes(x = diff_contrast, y = posterior_diff)) + 
    #stat_slab(alpha = 0.9, shape = 21, aes(fill = Gender)) +
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5,
               fill = met.brewer("Hiroshige", 10)[5]) +
  #scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
   geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Difference contrast") +
  ylab("% points") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12))

# expectation model

gender_expectation_draws <-
  fitted(foraging_model_expectation_gender, 
         newdata = new_data_gender_2, summary = F) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  pivot_longer(cols = 1:4, names_to = "Group", values_to = "Posterior_estimate") %>% 
  separate(sep = "_", col = Group, into = c("Treatment", "Gender")) %>%
  mutate(Posterior_estimate = Posterior_estimate*100) 
  
calculate_all_the_diffs_2 <-
  fitted(foraging_model_expectation_gender, 
         newdata = new_data_gender_2, summary = F) %>% 
  as_tibble() %>% 
  rename(Hungry_Woman = V1, Hungry_Man = V2, Satiated_Woman = V3, Satiated_Man = V4) %>% 
  mutate(Woman_h_s_diff = Hungry_Woman - Satiated_Woman,
         Man_h_s_diff = Hungry_Man - Satiated_Man,
         diff_diff = Woman_h_s_diff - Man_h_s_diff) %>% 
  select(contains("diff")) %>%
  rename(`H-S (women)` = Woman_h_s_diff,
         `H-S (men)` = Man_h_s_diff,
         `Interaction` = diff_diff) %>% 
  pivot_longer(cols = 1:3, names_to = "diff_contrast", values_to = "posterior_diff") %>% 
  mutate(posterior_diff = posterior_diff*100)

gp3 <- 
  gender_expectation_draws %>% 
  ggplot(aes(x = Gender, y = Posterior_estimate)) + 
    stat_slab(alpha = 0.9, shape = 21, aes(fill = Treatment)) +
  #stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
   #            point_interval = "median_qi", point_fill = "white",
   #            shape = 21, point_size = 4, stroke = 1.5,
   #            fill = met.brewer("Hiroshige", 5)[2]) +
  scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  labs(x = "Gender", y = "Estimated % pigeons foraging", fill = "Indicated\nexpectation") +
  theme_bw() + 
    theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 10))



gp4 <-
  calculate_all_the_diffs_2 %>% 
  ggplot(aes(x = diff_contrast, y = posterior_diff)) + 
    #stat_slab(alpha = 0.9, shape = 21, aes(fill = Gender)) +
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5,
               fill = met.brewer("Hiroshige", 10)[5]) +
  #scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
   geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Difference contrast") +
  ylab("% points") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12))

\(~\)

Question 2: is estimation of feeding rate affected by bias manipulations?

\(~\)

We asked observers to count the number of pecks of the ground that a selected pigeon made over a 1 minute period. We use the number of pecks that occur as a measure of feeding rate.

We first estimated a baseline peck rate by observing 35 pigeons. To select the pigeons we observed, we split a still image of the foraging video (taken at time zero) into a 43 x 21 cell grid. From the 122 cells that contained pigeons, 40 were chosen by random number generation (see code chunk below). In the event that multiple pigeons were present in the cell, we selected the most prominent to observe. Five observations were discarded - three due to overlap of the same pigeon between cells that were selected by the random number generator, and two more as the pigeons left the field of view during the video and could no longer be tracked.

# curly brackets run all lines included within them

{set.seed(1) # so that sample produces a reproducible sequence 
  sample(1:122, 40, replace = FALSE)}
##  [1] 121  68  39   1  34  87  43  14  82  59  51  97  85  21 106  54  74   7  73
## [20]  79 110  37  89 101 118 100  44 103  33  84  35  70 108  42  38  20  28 117
## [39]  96  91

The selected pigeons for baseline observation are shown in the image below

img <- readPNG("pigeon_selection.png")
 grid.raster(img)

\(~\)

Estimating baseline feeding rate

\(~\)

Load in the data

baseline_data <- read_csv("data/baseline_peck_data.csv") %>% 
  select(1:5) %>%  # remove the comments column
  pivot_longer(cols = 4:5, names_to = "Observation", values_to = "Peck_rate") %>% 
  mutate(ID = as.factor(ID),
         Observation = str_remove(Observation, "Peck_count_")) %>% 
  rename(Pigeon_ID = ID) %>% 
  filter(!is.na(Peck_rate))

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'baseline_dataset')),
      pageLength = 78
    )
  )
}


my_data_table(baseline_data)
  • X and Y represent grid coordinates.

  • Pigeon_ID identifies a specific pigeon

  • Observation indicates whether this was the first or second scoring for a single pigeon. We scored each pigeon twice as distant pigeons were difficult to observe and to ensure that the correct pigeon was tracked throughout the minute of observation.

  • Peck_rate is the number of times the ground was pecked over a minute of observation.

\(~\)

Fit a simple model to estimate median peck rate

baseline_peck_model_zi <-
  brm(Peck_rate ~ 1 + (1|Pigeon_ID),
      family = zero_inflated_negbinomial(), data = baseline_data,
      prior = c( prior(normal(0, 1.5), class = Intercept),
                 prior(exponential(1), class = sd),
                 prior(exponential(1), class = shape),
                 prior(exponential(1), class = zi)),
      chains = 4, cores = 4, warmup = 2000, iter = 6000,
      file = "fits/baseline_peck_model")

# wrangle the output

baseline_peck_predictions <-
  baseline_peck_model_zi %>% 
  as_draws_df() %>% 
  mutate(Baseline_estimate = exp(b_Intercept),
         peck_rate_sd = exp(sd_Pigeon_ID__Intercept)) %>% 
  select(Baseline_estimate, peck_rate_sd)

baseline_data %>% 
  distinct(Pigeon_ID) %>% 
  summarise(`n pigeons observed` = length(Pigeon_ID)) %>%
  bind_cols(
fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>% 
          as_tibble() %>%
          distinct(Estimate, .keep_all = T) %>% 
          mutate(across(1:4, round, 2)) %>% 
  rename(`Baseline median peck rate / per min` = Estimate)) %>%
  pander()
n pigeons observed Baseline median peck rate / per min Est.Error Q2.5 Q97.5
35 1.32 0.51 0.54 2.53

\(~\)

Experimental data

\(~\)

Exploring allocation versus expectation 2.0

\(~\)

Once again, we expect that attention paid to and/or comprehension of the primer statement has a large effect on observers’ perception of pigeon foraging.

Lets again fit our two models:

  1. a model with allocated primer (Bias_treatment) as the predictor variable

  2. a model with indicated hunger expectation (Expectation) as the predictor variable

\(~\)

Model 1: allocated primer

# First let's model the effect of bias treatment on peck rate

peck_model_treatment <- 
  brm(Peck_rate ~ 0 + Bias_treatment + (1|Observer_ID),
      data = data_peck, family = negbinomial,
      prior = c(prior(normal(0, 1.5), class = b),
                prior(exponential(1), class = sd)),
      iter = 6000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.9, max_treedepth = 12),
      seed = 1, file = "fits/peck_model_treatment")

peck_model_treatment <- add_criterion(peck_model_treatment, criterion = "loo", file = "fits/peck_model_treatment")
  
peck_model_treatment
##  Family: negbinomial 
##   Links: mu = log; shape = identity 
## Formula: Peck_rate ~ 0 + Bias_treatment + (1 | Observer_ID) 
##    Data: data_peck (Number of observations: 156) 
##   Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
##          total post-warmup draws = 16000
## 
## Group-Level Effects: 
## ~Observer_ID (Number of levels: 78) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.21      0.15     0.01     0.54 1.00     4493     7497
## 
## Population-Level Effects: 
##                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Bias_treatmentHungry       2.32      0.13     2.06     2.57 1.00    14993
## Bias_treatmentSatiated     2.16      0.14     1.89     2.44 1.00    19527
##                        Tail_ESS
## Bias_treatmentHungry      10405
## Bias_treatmentSatiated    11645
## 
## Family Specific Parameters: 
##       Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## shape     0.91      0.13     0.69     1.18 1.00    13608     8978
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
peck_model_treatment_gender <- 
  brm(Peck_rate ~ 0 + Gender * Bias_treatment + (1|Observer_ID),
      data = data_peck, family = negbinomial,
      prior = c(prior(normal(0, 1.5), class = b),
                prior(exponential(1), class = sd)),
      iter = 6000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.9, max_treedepth = 12),
      seed = 1, file = "fits/peck_model_treatment_gender")

Table S3. The estimated peck rate of foraging pigeons, split by the primer observers were allocated.

new_data %>% 
  bind_cols(fitted(peck_model_treatment, newdata = new_data, summary = T, re_formula = NA) %>% 
              as_tibble() %>% 
              mutate(across(1:4, round, 2))) %>% 
  left_join(data_peck %>% group_by(Bias_treatment) %>% 
              distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>% 
  rename("Estimated peck rate" = Estimate,
         "Bias treatment" = Bias_treatment) %>% 
  bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>% 
              as_tibble() %>%
              distinct(Estimate, .keep_all = T) %>% 
              mutate(across(1:4, round, 2)) %>% 
              rename("Estimated peck rate" = Estimate) %>% 
              mutate(`Bias treatment` = "Baseline") %>% 
              bind_cols(baseline_data %>% 
                          distinct(Pigeon_ID) %>% 
                          summarise(`n pigeons observed` = length(Pigeon_ID)))) %>% 
  select(`Bias treatment`, `n pigeons observed`, everything()) %>% 
  pander(split.cell = 20, split.table = Inf)
Bias treatment n pigeons observed Estimated peck rate Est.Error Q2.5 Q97.5
Hungry 42 10.23 1.34 7.83 13.12
Satiated 36 8.74 1.24 6.59 11.44
Baseline 35 1.32 0.51 0.54 2.53

add the gender specific estimates

# add the gender table

new_data_gender %>% 
  bind_cols(fitted(peck_model_treatment_gender, 
               newdata = new_data_gender, summary = T, re_formula = NA) %>% 
          as_tibble() %>% 
          mutate(across(1:4, round, 2))) %>% 
  left_join(data_peck %>% group_by(Bias_treatment, Gender) %>% 
               distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>% 
    rename("Estimated peck rate" = Estimate,
         "Bias treatment" = Bias_treatment) %>% 
  bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>% 
              as_tibble() %>%
              distinct(Estimate, .keep_all = T) %>% 
              mutate(across(1:4, round, 2)) %>% 
              rename("Estimated peck rate" = Estimate) %>% 
              mutate(`Bias treatment` = "Baseline", Gender = "-") %>% 
              bind_cols(baseline_data %>% 
                          distinct(Pigeon_ID) %>% 
                          summarise(`n pigeons observed` = length(Pigeon_ID)))) %>% 
  select(`Bias treatment`, `n pigeons observed`, everything()) %>% 
  pander(split.cell = 20, split.table = Inf)
Bias treatment n pigeons observed Gender Estimated peck rate Est.Error Q2.5 Q97.5
Hungry 30 Woman 10.84 1.68 7.91 14.51
Hungry 11 Man 8.52 2.25 4.95 13.61
Satiated 27 Woman 9.34 1.56 6.71 12.82
Satiated 9 Man 8.12 2.37 4.63 13.7
Baseline 35 - 1.32 0.51 0.54 2.53

Model 2: Indicated expectation

# fit the same model, except using participant expectation rather than allocated bias treatment

peck_model_expectation <- brm(Peck_rate ~ 0 + Expectation + (1|Observer_ID),
                                     data = data_peck, family = negbinomial,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = sd)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.95, max_treedepth = 12),
                                     seed = 1, file = "fits/peck_model_expectation")

peck_model_expectation <- add_criterion(peck_model_expectation, criterion = "loo", file = "fits/peck_model_expectation")


peck_model_expectation
##  Family: negbinomial 
##   Links: mu = log; shape = identity 
## Formula: Peck_rate ~ 0 + Expectation + (1 | Observer_ID) 
##    Data: data_peck (Number of observations: 156) 
##   Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
##          total post-warmup draws = 16000
## 
## Group-Level Effects: 
## ~Observer_ID (Number of levels: 78) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.18      0.13     0.01     0.48 1.00     4710     7228
## 
## Population-Level Effects: 
##                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## ExpectationHungry       2.41      0.12     2.18     2.66 1.00    16705    11820
## ExpectationSatiated     2.00      0.14     1.73     2.28 1.00    18644    12176
## 
## Family Specific Parameters: 
##       Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## shape     0.93      0.12     0.71     1.20 1.00    14884    11083
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
#loo_compare(peck_model_treatment, peck_model_expectation)

peck_model_expectation_gender <- brm(Peck_rate ~ 0 + Gender * Expectation + (1|Observer_ID),
                                     data = data_peck, family = negbinomial,
                                     prior = c(prior(normal(0, 1.5), class = b),
                                               prior(exponential(1), class = sd)),
                                     iter = 6000, warmup = 2000, chains = 4, cores = 4,
                                     control = list(adapt_delta = 0.95, max_treedepth = 12),
                                     seed = 1, file = "fits/peck_model_expectation_gender")

Table S4. The estimated peck rate of foraging pigeons, split by the indicated expectation of the observers.

new_data_2 %>% 
  bind_cols(fitted(peck_model_expectation, newdata = new_data_2, summary = T, re_formula = NA) %>% 
              as_tibble() %>% 
              mutate(across(1:4, round, 2))) %>% 
  left_join(data_peck %>% group_by(Expectation) %>% 
              distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>% 
  rename("Estimated peck rate" = Estimate,
         "Indicated expectation" = Expectation) %>% 
  bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>% 
              as_tibble() %>%
              distinct(Estimate, .keep_all = T) %>% 
              mutate(across(1:4, round, 2)) %>% 
              rename("Estimated peck rate" = Estimate) %>% 
              mutate(`Indicated expectation` = "Baseline") %>% 
              bind_cols(baseline_data %>% 
                          distinct(Pigeon_ID) %>% 
                          summarise(`n pigeons observed` = length(Pigeon_ID)))) %>% 
  select(`Indicated expectation`, `n pigeons observed`, everything()) %>% 
  pander(split.cell = 20, split.table = Inf)
Indicated expectation n pigeons observed Estimated peck rate Est.Error Q2.5 Q97.5
Hungry 44 11.27 1.4 8.81 14.29
Satiated 34 7.46 1.06 5.62 9.81
Baseline 35 1.32 0.51 0.54 2.53

add the gender specific estimates

# add the gender table

new_data_gender_2 %>% 
  bind_cols(fitted(peck_model_expectation_gender, 
               newdata = new_data_gender_2, summary = T, re_formula = NA) %>% 
          as_tibble() %>% 
          mutate(across(1:4, round, 2))) %>% 
  left_join(data_peck %>% group_by(Expectation, Gender) %>% 
               distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>% 
    rename("Estimated peck rate" = Estimate,
         "Indicated expectation" = Expectation) %>% 
  bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>% 
              as_tibble() %>%
              distinct(Estimate, .keep_all = T) %>% 
              mutate(across(1:4, round, 2)) %>% 
              rename("Estimated peck rate" = Estimate) %>% 
              mutate(`Indicated expectation` = "Baseline", Gender = "-") %>% 
              bind_cols(baseline_data %>% 
                          distinct(Pigeon_ID) %>% 
                          summarise(`n pigeons observed` = length(Pigeon_ID)))) %>% 
  select(`Indicated expectation`, `n pigeons observed`, everything()) %>% 
  pander(split.cell = 20, split.table = Inf)
Indicated expectation n pigeons observed Gender Estimated peck rate Est.Error Q2.5 Q97.5
Hungry 32 Woman 11.94 1.74 8.94 15.76
Hungry 12 Man 9.12 2.25 5.56 14.3
Satiated 25 Woman 7.88 1.34 5.61 10.85
Satiated 8 Man 7.34 2.25 4.05 12.78
Baseline 35 - 1.32 0.51 0.54 2.53

\(~\)

Build Figure 2e-h

\(~\)

Get posterior means and difference contrasts

# treatment model

peck_draws_treatment <-
  as_draws_df(peck_model_treatment) %>% 
  mutate(Hungry = exp(b_Bias_treatmentHungry),
         Satiated = exp(b_Bias_treatmentSatiated),
         diff_contrast = (Hungry - Satiated)) %>% 
  select(Hungry, Satiated, diff_contrast) %>%
  bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>% 
  pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>% 
  mutate(Predictor = "Allocated primer")


p6 <- 
    peck_draws_treatment %>% 
    filter(Treatment != "diff_contrast") %>% 
    ggplot(aes(x = Treatment, y = Posterior_estimate)) +
    stat_slab(aes(y = Baseline_estimate),
              linetype = 2, linewidth = 0.8, slab_fill = "white",
              colour = "black") +
    stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
                 point_interval = "median_qi", point_fill = "white",
                 shape = 21, point_size = 4, stroke = 1.5) +
    scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
    coord_flip(ylim = c(0, 20)) +
    #geom_vline(xintercept = 0, linetype = 2) +
    #scale_y_continuous(breaks = c(, 0, 1)) +
    xlab("Allocated primer") +
    ylab("Estimated pecks per min") +
    theme_bw() + 
    theme(legend.position = "none",
          panel.grid.minor = element_blank(),
          text = element_text(size = 14))

p7 <-
  peck_draws_treatment %>% 
  filter(Treatment == "diff_contrast") %>% 
  ggplot(aes(y = Posterior_estimate)) + 
   stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
  scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
  coord_flip(ylim = c(-5, 12)) +
  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab(NULL) +
  ylab("Hungry - Satiated difference\ncontrast (pecks per min)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        text = element_text(size = 14))

# expectation model

peck_draws_expectation <-
  as_draws_df(peck_model_expectation) %>% 
  mutate(Hungry = exp(b_ExpectationHungry),
         Satiated = exp(b_ExpectationSatiated),
         diff_contrast = (Hungry - Satiated)) %>% 
  select(Hungry, Satiated, diff_contrast) %>% 
  bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>% 
  pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>% 
  mutate(Predictor = "Allocated primer")

p8 <-
  peck_draws_expectation %>% 
  filter(Treatment != "diff_contrast") %>% 
  ggplot(aes(x = Treatment, y = Posterior_estimate)) + 
  stat_slab(aes(y = Baseline_estimate),
              linetype = 2, linewidth = 0.8, slab_fill = "white",
              colour = "black") +
    stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5) +
  scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip(ylim = c(0, 20)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab("Indicated expectation") +
  ylab("Estimated pecks per min") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 14))

p9 <-
  peck_draws_expectation %>% 
  filter(Treatment == "diff_contrast") %>% 
  ggplot(aes(y = Posterior_estimate)) + 
   stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
  scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
  coord_flip(ylim = c(-5, 12)) +
  geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  xlab(NULL) +
  ylab("Hungry - Satiated difference\ncontrast (pecks per min)") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        text = element_text(size = 14))

Now for the gender models

# with gender

gender_treatment_draws_2 <-
  fitted(peck_model_treatment_gender, 
         newdata = new_data_gender, summary = F, re_formula = NA) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>% 
  pivot_longer(names_to = "Group", values_to = "Posterior_estimate", cols = 1:4) %>% 
  separate(sep = "_", col = Group, into = c("Treatment", "Gender"))
  
calculate_all_the_diffs_3 <-
  fitted(peck_model_treatment_gender, 
         newdata = new_data_gender, summary = F, re_formula = NA) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  mutate(Women_h_s_diff = Hungry_Women - Satiated_Women,
         Men_h_s_diff = Hungry_Men - Satiated_Men,
         diff_diff = Women_h_s_diff - Men_h_s_diff) %>% 
  select(contains("diff")) %>%
  rename(`H-S (women)` = Women_h_s_diff,
         `H-S (men)` = Men_h_s_diff,
         `Interaction` = diff_diff) %>% 
  pivot_longer(cols = 1:3, names_to = "diff_contrast", values_to = "posterior_diff")

gp5 <- 
  gender_treatment_draws_2 %>% 
  ggplot(aes(x = Gender, y = Posterior_estimate)) + 
    stat_slab(alpha = 0.8, shape = 21, aes(fill = Treatment)) +
  stat_slab(aes(y = Baseline_estimate),
              linetype = 2, linewidth = 0.8, slab_fill = "white",
              colour = "black") +
  #stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
   #            point_interval = "median_qi", point_fill = "white",
   #            shape = 21, point_size = 4, stroke = 1.5,
   #            fill = met.brewer("Hiroshige", 5)[2]) +
  scale_fill_manual(values = c(met.brewer("Hiroshige", 10)[4], met.brewer("Hiroshige", 10)[6])) +
  coord_flip()+#ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  labs(x = "Gender", y = "Estimated pecks per min", fill = "Allocated\nPrimer") +
  theme_bw() + 
    theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 10))



gp6 <-
  calculate_all_the_diffs_3 %>% 
  ggplot(aes(x = diff_contrast, y = posterior_diff)) + 
    #stat_slab(alpha = 0.9, shape = 21, aes(fill = Gender)) +
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5,
               fill = met.brewer("Hiroshige", 10)[5]) +
  #scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
   geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #geom_vline(xintercept = 0, linetype = 2) +
  scale_y_continuous(limits = c(-10, 15)) +
  xlab("Difference contrast") +
  ylab("Pecks per min") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12))


# expectation model

gender_expectation_draws_2 <-
  fitted(peck_model_expectation_gender, 
         newdata = new_data_gender_2, summary = F, re_formula = NA) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>% 
  pivot_longer(names_to = "Group", values_to = "Posterior_estimate", cols = 1:4) %>% 
  separate(sep = "_", col = Group, into = c("Treatment", "Gender"))
  
calculate_all_the_diffs_4 <-
  fitted(peck_model_expectation_gender, 
         newdata = new_data_gender_2, summary = F, re_formula = NA) %>% 
  as_tibble() %>% 
  rename(Hungry_Women = V1, Hungry_Men = V2, Satiated_Women = V3, Satiated_Men = V4) %>% 
  mutate(Women_h_s_diff = Hungry_Women - Satiated_Women,
         Men_h_s_diff = Hungry_Men - Satiated_Men,
         diff_diff = Women_h_s_diff - Men_h_s_diff) %>% 
  select(contains("diff")) %>%
  rename(`H-S (women)` = Women_h_s_diff,
         `H-S (men)` = Men_h_s_diff,
         `Interaction` = diff_diff) %>% 
  pivot_longer(cols = 1:3, names_to = "diff_contrast", values_to = "posterior_diff")

gp7 <- 
  gender_expectation_draws_2 %>% 
  ggplot(aes(x = Gender, y = Posterior_estimate)) + 
    stat_slab(alpha = 0.9, shape = 21, aes(fill = Treatment)) +
  stat_slab(aes(y = Baseline_estimate),
              linetype = 2, linewidth = 0.8, slab_fill = "white",
              colour = "black") +
  #stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
   #            point_interval = "median_qi", point_fill = "white",
   #            shape = 21, point_size = 4, stroke = 1.5,
   #            fill = met.brewer("Hiroshige", 5)[2]) +
  scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
  #geom_vline(xintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(, 0, 1)) +
  labs(x = "Gender", y = "Estimated pecks per min", fill = "Indicated\nexpectation") +
  theme_bw() + 
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 10))



gp8 <-
  calculate_all_the_diffs_4 %>% 
  ggplot(aes(x = diff_contrast, y = posterior_diff)) + 
    #stat_slab(alpha = 0.9, shape = 21, aes(fill = Gender)) +
  stat_halfeye(.width = c(0.66, 0.95), alpha = 0.9,
               point_interval = "median_qi", point_fill = "white",
               shape = 21, point_size = 3, stroke = 1.5,
               fill = met.brewer("Hiroshige", 10)[5]) +
  #scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
  coord_flip()+#ylim = c(25, 55)) +
   geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
  #geom_vline(xintercept = 0, linetype = 2) +
  scale_y_continuous(limits = c(-10, 15)) +
  xlab("Difference contrast") +
  ylab("Pecks per min") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size = 12))

\(~\)

Find the difference between baseline and observer estimates

Table S5. The degree to which each group of observer’s overestimates feeding rate (number of ground pecks per minute)

baseline_peck_predictions %>% select(Baseline_estimate) %>%  bind_cols(
  
  as_draws_df(peck_model_treatment) %>% 
    mutate(Hungry = exp(b_Bias_treatmentHungry),
           Satiated = exp(b_Bias_treatmentSatiated)) %>% 
    select(Hungry, Satiated)) %>% 
  mutate(`Bias treatment Satiated / Baseline` = Satiated / Baseline_estimate,
         `Bias treatment Hungry / Baseline` = Hungry / Baseline_estimate) %>% 
  select(contains("Bias")) %>% 
  pivot_longer(cols = everything(), values_to = "estimate", names_to = "Stat") %>% 
  group_by(Stat) %>% 
  summarise_draws("median", "sd", ~quantile(.x, probs = c(0.025, 0.975), na.rm = TRUE), .cores = 4) %>% 
  select(-variable) %>% 
  
  bind_rows(
    
    baseline_peck_predictions %>% select(Baseline_estimate) %>%  bind_cols(
      
      as_draws_df(peck_model_expectation) %>% 
        mutate(Hungry = exp(b_ExpectationHungry),
               Satiated = exp(b_ExpectationSatiated)) %>% 
        select(Hungry, Satiated)) %>% 
      mutate(`Expectation Satiated / Baseline` = Satiated / Baseline_estimate,
             `Expectation Hungry / Baseline` = Hungry / Baseline_estimate) %>% 
      select(contains("Expectation")) %>% 
      pivot_longer(cols = everything(), values_to = "estimate", names_to = "Stat") %>% 
      group_by(Stat) %>% 
      summarise_draws("median", "sd", ~quantile(.x, probs = c(0.025, 0.975), na.rm = TRUE), .cores = 4) %>% 
      select(-variable)
  ) %>% 
  pander()
Stat median sd 2.5% 97.5%
Bias treatment Hungry / Baseline 7.883 4.111 3.728 19.04
Bias treatment Satiated / Baseline 6.713 3.562 3.149 16.48
Expectation Hungry / Baseline 8.67 4.554 4.108 20.94
Expectation Satiated / Baseline 5.722 3.065 2.688 14

Figure 2

Option 1

(p2 + p3) / (p4 + p5) / (p6 + p7) / (p8 + p9) +
   plot_annotation(tag_levels = 'a')

Option 2

(gp1 + gp2) / (gp3 + gp4) / (gp5 + gp6) / (gp7 + gp8) +
   plot_annotation(tag_levels = 'a')

Figure 2. Posterior mean estimates and difference contrasts for observer estimated group foraging percentage and individual feeding rates. The coloured area is the posterior distribution and the white point is the mean estimate with associated 67% and 95% credible intervals.

Session info

sessionInfo() %>% pander

R version 4.2.2 (2022-10-31 ucrt)

Platform: x86_64-w64-mingw32/x64 (64-bit)

locale: LC_COLLATE=English_United Kingdom.utf8, LC_CTYPE=English_United Kingdom.utf8, LC_MONETARY=English_United Kingdom.utf8, LC_NUMERIC=C and LC_TIME=English_United Kingdom.utf8

attached base packages: grid, stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: ggdag(v.0.2.8), png(v.0.1-8), pander(v.0.6.5), DT(v.0.28), patchwork(v.1.1.2), kableExtra(v.1.3.4), MetBrewer(v.0.2.0), tidybayes(v.3.0.4), loo(v.2.6.0), brms(v.2.19.0), Rcpp(v.1.0.10), lubridate(v.1.9.2), forcats(v.1.0.0), stringr(v.1.5.0), dplyr(v.1.1.2), purrr(v.1.0.1), readr(v.2.1.4), tidyr(v.1.3.0), tibble(v.3.2.1), ggplot2(v.3.4.2) and tidyverse(v.2.0.0)

loaded via a namespace (and not attached): backports(v.1.4.1), systemfonts(v.1.0.4), plyr(v.1.8.8), igraph(v.1.4.2), svUnit(v.1.0.6), crosstalk(v.1.2.0), rstantools(v.2.3.1), inline(v.0.3.19), digest(v.0.6.31), htmltools(v.0.5.5), viridis(v.0.6.3), fansi(v.1.0.4), magrittr(v.2.0.3), checkmate(v.2.2.0), tzdb(v.0.4.0), graphlayouts(v.1.0.0), RcppParallel(v.5.1.7), matrixStats(v.0.63.0), vroom(v.1.6.3), xts(v.0.13.1), svglite(v.2.1.1), timechange(v.0.2.0), prettyunits(v.1.1.1), colorspace(v.2.1-0), ggrepel(v.0.9.3), rvest(v.1.0.3), ggdist(v.3.3.0), xfun(v.0.39), callr(v.3.7.3), crayon(v.1.5.2), jsonlite(v.1.8.4), zoo(v.1.8-12), glue(v.1.6.2), polyclip(v.1.10-4), gtable(v.0.3.3), webshot(v.0.5.4), V8(v.4.3.0), distributional(v.0.3.2), pkgbuild(v.1.4.0), rstan(v.2.26.13), abind(v.1.4-5), scales(v.1.2.1), mvtnorm(v.1.1-3), miniUI(v.0.1.1.1), viridisLite(v.0.4.2), xtable(v.1.8-4), bit(v.4.0.5), stats4(v.4.2.2), StanHeaders(v.2.26.25), htmlwidgets(v.1.6.2), httr(v.1.4.6), threejs(v.0.3.3), arrayhelpers(v.1.1-0), posterior(v.1.4.1), ellipsis(v.0.3.2), pkgconfig(v.2.0.3), farver(v.2.1.1), sass(v.0.4.6), utf8(v.1.2.3), labeling(v.0.4.2), tidyselect(v.1.2.0), rlang(v.1.1.1), reshape2(v.1.4.4), later(v.1.3.1), munsell(v.0.5.0), dagitty(v.0.3-1), tools(v.4.2.2), cachem(v.1.0.8), cli(v.3.5.0), generics(v.0.1.3), evaluate(v.0.21), fastmap(v.1.1.1), yaml(v.2.3.7), processx(v.3.8.1), knitr(v.1.42), bit64(v.4.0.5), tidygraph(v.1.2.3), ggraph(v.2.1.0), nlme(v.3.1-160), mime(v.0.12), xml2(v.1.3.4), compiler(v.4.2.2), bayesplot(v.1.10.0), shinythemes(v.1.2.0), rstudioapi(v.0.14), curl(v.5.0.0), tweenr(v.2.0.2), bslib(v.0.4.2), stringi(v.1.7.12), highr(v.0.10), ps(v.1.7.5), Brobdingnag(v.1.2-9), lattice(v.0.20-45), Matrix(v.1.5-1), markdown(v.1.7), shinyjs(v.2.1.0), tensorA(v.0.36.2), vctrs(v.0.6.2), pillar(v.1.9.0), lifecycle(v.1.0.3), jquerylib(v.0.1.4), bridgesampling(v.1.1-2), httpuv(v.1.6.10), R6(v.2.5.1), promises(v.1.2.0.1), gridExtra(v.2.3), codetools(v.0.2-18), boot(v.1.3-28), colourpicker(v.1.2.0), MASS(v.7.3-58.1), gtools(v.3.9.4), withr(v.2.5.0), shinystan(v.2.6.0), parallel(v.4.2.2), hms(v.1.1.3), coda(v.0.19-4), rmarkdown(v.2.21), ggforce(v.0.4.1), shiny(v.1.7.4), base64enc(v.0.1-3) and dygraphs(v.1.1.1.6)

LS0tDQp0aXRsZTogJ09ic2VydmF0aW9uYWwgYmlhcyBpbiBiZWhhdmlvdXJhbCBlY29sb2d5OiBhIGNhc2Ugc3R1ZHkgYW5kIHRlYWNoaW5nIHRvb2wnDQphdXRob3I6ICdUaG9tYXMgS2VhbmV5LCBUaGVyZXNhIEpvbmVzIGFuZCBSYW91bCBNdWxkZXInIA0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGRlcHRoOiAxDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOg0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBGQUxTRSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKSAjIHRpZHkgc3R5bGUgY29kaW5nDQpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzDQpsaWJyYXJ5KGxvbykgIyBmb3IgaW5mb3JtYXRpb24gY3JpdGVyaWENCmxpYnJhcnkodGlkeWJheWVzKSAjIEJheWVzaWFuIGFlc3RoZXRpY3MNCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMNCmxpYnJhcnkoa2FibGVFeHRyYSkgIyB0YWJsZXMNCmxpYnJhcnkocGF0Y2h3b3JrKSAjIHB1dHRpbmcgcGxvdHMgdG9nZXRoZXINCmxpYnJhcnkoRFQpICMgZm9yIHNlYXJjaC0gYW5kIHNhdmVhYmxlIHRhYmxlcw0KbGlicmFyeShwYW5kZXIpICMgZm9yIHNpbXBsZXIgdGFibGVzDQpsaWJyYXJ5KHBuZykgIyB0byBsb2FkIGltYWdlcw0KbGlicmFyeShncmlkKSAjIHRvIHBsb3QgaW1hZ2VzDQpsaWJyYXJ5KGdnZGFnKSAjIHRvIGRyYXcgZGFncw0KYGBgDQoNCiMgTG9hZCBpbiB0aGUgZGF0YQ0KDQpXZSBhbmFseXNlIGRhdGEgY29sbGVjdGVkIGFjcm9zcyB0aHJlZSBjb2hvcnRzIG9mIHN0dWRlbnRzICgyMDIxLTIwMjMpIGVucm9sbGVkIGluIHRoZSB0aGlyZCB5ZWFyIFNjaG9vbCBvZiBCaW9zY2llbmNlcyBzdWJqZWN0LCBfQW5pbWFsIEJlaGF2aW91cl8sIGF0IFRoZSBVbml2ZXJzaXR5IG9mIE1lbGJvdXJuZS4gV2UgaGVyZWFmdGVyIHJlZmVyIHRvIHN0dWRlbnRzIGFzIG9ic2VydmVycy4NCg0KYGBge3J9DQoNCmRhdGEgPC0gcmVhZF9jc3YoImRhdGEvcGlnZW9uX2RhdGEuY3N2IikgJT4lIA0KICBtdXRhdGUoU3R1ZGVudF9JRCA9IGFzLmZhY3RvcihTdHVkZW50X0lEKSwNCiAgICAgICAgIFllYXIgPSBhcy5mYWN0b3IoWWVhciksDQogICAgICAgICBGb3JhZ2luZ19wcm9wID0gKEZvcmFnaW5nX3BlcmNlbnRhZ2UgLyAxMDApKSAlPiUNCiAgZmlsdGVyKFllYXIgJWluJSBjKCIyMDIxIiwgIjIwMjIiLCAiMjAyMyIpLA0KICAgICAgICAgRm9yYWdpbmdfcGVyY2VudGFnZSAhPSAiTkEiLA0KICAgICAgICAgUHJpbWVyX3VuZGVyc3Rvb2QgIT0gIk5BIikgJT4lDQogIGZpbHRlcihTdHVkZW50X0lEICE9ICI2MCIgJiBTdHVkZW50X0lEICE9ICI2OCIgJiBTdHVkZW50X0lEICE9ICI3MCIgJiBTdHVkZW50X0lEICE9ICI3MiIpICU+JSAjIHJlbW92ZSBzdHVkZW50cyB0aGF0IGNvbXBsZXRlZCB0aGUgdGFzayBtdWx0aXBsZSB0aW1lcw0KICAjU3R1ZGVudF9JRCAlaW4lIGMoIjYwIiwgIjY4IiwgIjcwIiwgIjcyIikpICU+JSANCiAgc2VsZWN0KC1jKEZpcnN0X25hbWUsIFN1cm5hbWUsIFBlY2tfbWVhbikpICU+JSAgIyByZW1vdmUgbmFtZXMgd2hlbiByZWFkeQ0KICBsZWZ0X2pvaW4oDQogICAgcmVhZF9jc3YoImRhdGEvZ2VuZGVyX2RhdGEuY3N2IikgJT4lIA0KICAgICAgbXV0YXRlKFN0dWRlbnRfSUQgPSBhcy5mYWN0b3IoU3R1ZGVudF9JRCkpDQogICkgJT4lIA0KICByZW5hbWUoT2JzZXJ2ZXJfSUQgPSBTdHVkZW50X0lEKSAlPiUgDQogIHNlbGVjdChPYnNlcnZlcl9JRCwgWWVhciwgR2VuZGVyLCBldmVyeXRoaW5nKCkpDQoNCmRhdGFfcGVjayA8LSANCiAgZGF0YSAlPiUNCiAgZmlsdGVyKFBlY2tfcmF0ZV8yICE9ICJOQSIpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBQZWNrX3JhdGVfMTpQZWNrX3JhdGVfMiwgbmFtZXNfdG8gPSAiVHJpYWwiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlBlY2tfcmF0ZSIpDQogIA0KIyBDcmVhdGUgYSBmdW5jdGlvbiB0byBidWlsZCBIVE1MIHNlYXJjaGFibGUgdGFibGVzDQoNCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpew0KICBkYXRhdGFibGUoDQogICAgZGYsIHJvd25hbWVzPUZBTFNFLA0KICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsDQogICAgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgICJCdXR0b25zIiksDQogICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgIGRlZmVyUmVuZGVyPVRSVUUsDQogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLA0KICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwNCiAgICAgIGJ1dHRvbnMgPQ0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KA0KICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLA0KICAgICAgICAgIHBhZ2VTaXplID0gJ0E0JywNCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLA0KICAgICAgICAgIGZpbGVuYW1lID0gJ2Z1bGxfZGF0YXNldCcpKSwNCiAgICAgIHBhZ2VMZW5ndGggPSA3OA0KICAgICkNCiAgKQ0KfQ0KDQoNCm15X2RhdGFfdGFibGUoZGF0YSkNCg0KYGBgDQoNCioqQ29sdW1uIGV4cGxhbmF0aW9ucyoqDQoNCioqT2JzZXJ2ZXJfSUQqKjogdW5pcXVlLCBhbm9ueW1pc2VkIGlkZW50aWZpZXIgZm9yIGVhY2ggb2JzZXJ2ZXIuDQoNCioqWWVhcioqOiB5ZWFyIHRoYXQgdGhlIGV4cGVyaW1lbnQgd2FzIGNvbmR1Y3RlZC4NCg0KKipHZW5kZXIqKjogdXBvbiBlbnJvbGxtZW50IGF0IFRoZSBVbml2ZXJzaXR5IG9mIE1lbGJvdXJuZSwgc3R1ZGVudHMgYXJlIGFza2VkIHRvIGluZGljYXRlIHRoZWlyIHRpdGxlLiBXZSBpZGVudGlmaWVkIHdvbWVuIGFzIG9ic2VydmVycyB0aGF0IGFuc3dlcmVkICJNaXNzIiBvciAiTXMiIGFuZCBNZW4gYXMgdGhvc2Ugd2hvIHRoYXQgYW5zd2VyZWQgIk1yIi4gVGhvc2Ugd2l0aCBlbnRpcmVseSBtaXNzaW5nIGVudHJpZXMgd2VyZSBjb2RlZCBhcyAiTkEiLiAgDQoNCioqQmlhc190cmVhdG1lbnQqKjogdGhlIHByaW1lciB0aGUgb2JzZXJ2ZXIgcmVjZWl2ZWQsIHdoZXJlICdzYXRpYXRlZCcgaW5kaWNhdGVzIHRoYXQgdGhlIG9ic2VydmVycyB3ZXJlIHByb3ZpZGVkIGluZm9ybWF0aW9uIHByaW9yIHRvIGEgdHJpYWwgdGhhdCBzdWdnZXN0ZWQgcGlnZW9ucyB3ZXJlIGZlbGwgZmVkLCB3aGVyZWFzICdodW5ncnknIGluZGljYXRlZCB0aGF0IHRoZSBwaWdlb25zIHdlcmUgaW4gcG9vciBjb25kaXRpb24gYW5kIGh1bmdyeS4NCg0KKipFeHBlY3RhdGlvbioqOiB3ZSBhc2tlZCB0aGUgb2JzZXJ2ZXJzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhleSB0aG91Z2h0IHRoZSBwaWdlb25zIHdvdWxkIGJlIGh1bmdyeSBvciBzYXRpYXRlZC4gV2UgaW5jbHVkZWQgdGhpcyBxdWVzdGlvbiB0byB0ZXN0IHdoZXRoZXIgb2JzZXJ2ZXJzIHdlcmUgYXBwcm9wcmlhdGVseSBwcmltZWQgYnkgdGhlaXIgYmlhcyB0cmVhdG1lbnQuDQoNCioqUHJpbWVyX3VuZGVyc3Rvb2QqKjogZGlkIHRoZSBvYnNlcnZlcidzIGV4cGVjdGF0aW9uIG1hdGNoIHRoZSBwcmltZXIgdGhleSByZWNlaXZlZD8NCg0KKipGb3JhZ2luZ19wZXJjZW50YWdlKio6IHRoZSBwZXJjZW50YWdlIG9mIHBpZ2VvbnMgdGhhdCBvYnNlcnZlcnMgZXN0aW1hdGVkIHRvIGJlIGZvcmFnaW5nIG92ZXIgYSAxNSBzZWNvbmQgcGVyaW9kLCB3aGlsZSBvYnNlcnZpbmcgYSBsYXJnZSBmbG9jay4NCg0KKipQZWNrX3JhdGVfMSoqOiB0aGUgbnVtYmVyIG9mIHRpbWVzIGEgc2luZ2xlIGNob3NlbiBwaWdlb24gcGVja2VkIHRoZSBncm91bmQgb3ZlciBhIDE1IHNlY29uZCBwZXJpb2QuDQoNCioqUGVja19yYXRlXzIqKjogdGhlIG51bWJlciBvZiB0aW1lcyBhIHNlY29uZCBjaG9zZW4gcGlnZW9uIHBlY2tlZCB0aGUgZ3JvdW5kIG92ZXIgYSAxNSBzZWNvbmQgcGVyaW9kLg0KDQoqKkZvcmFnaW5nX3Byb3AqKjogcHJvcG9ydGlvbiBvZiBwaWdlb25zIGVzdGltYXRlZCB0byBiZSBmb3JhZ2luZyANCg0KJH4kDQoNCiMgUXVlc3Rpb24gMTogaXMgZXN0aW1hdGlvbiBvZiBmb3JhZ2luZyBwZXJjZW50YWdlIGFmZmVjdGVkIGJ5IGJpYXMgbWFuaXB1bGF0aW9ucz8NCg0KJH4kDQoNCiMjIEV4cGxvcmluZyBhbGxvY2F0aW9uIHZlcnN1cyBleHBlY3RhdGlvbiAxIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiR+JA0KDQpXZSBmaW5kIHRoYXQgKioyMiBvZiB0aGUgNzggb2JzZXJ2ZXJzKiogaW5kaWNhdGVkIGEgZmVlZGluZyBtb3RpdmF0aW9uIGV4cGVjdGF0aW9uIG9wcG9zaXRlIHRvIHRoYXQgaW1wbGllZCBieSB0aGUgcHJpbWVyIHRoZXkgd2VyZSBhbGxvY2F0ZWQuIA0KDQpUaGlzIHN1Z2dlc3RzIHRoYXQgYEV4cGVjdGF0aW9uYCBtYXkgYmUgYSBiZXR0ZXIgcHJlZGljdG9yIG9mIGZvcmFnaW5nIGVzdGltYXRpb24gdGhhbiBhbGxvY2F0ZWQgYEJpYXNfdHJlYXRtZW50YC4gVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZXNlIGFuZCBhbGwgb3RoZXIgdmFyaWFibGVzIHRoYXQgd2UgZXhwZWN0IHRvIHBsYXkgYSByb2xlIGluIHRoaXMgc3lzdGVtIGFyZSBkZXBpY3RlZCBpbiBGaWd1cmUgMS4NCg0KV2UgZXhwbGljaXRseSBhc3Nlc3MgdGhlIGVmZmVjdCBvZiB0cmVhdG1lbnQgYW5kIGV4cGVjdGF0aW9uIGJ5IGZpdHRpbmcgdHdvIG1vZGVsczoNCg0KMS4gYSBtb2RlbCB3aXRoIGFsbG9jYXRlZCBwcmltZXIgKGBCaWFzX3RyZWF0bWVudGApIGFzIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUgDQoNCjIuIGEgbW9kZWwgd2l0aCBpbmRpY2F0ZWQgaHVuZ2VyIGV4cGVjdGF0aW9uIChgRXhwZWN0YXRpb25gKSBhcyB0aGUgcHJlZGljdG9yIHZhcmlhYmxlDQoNCiR+JA0KDQpgYGB7cn0NCmdnX3NpbXBsZV9kYWcgPC0gZnVuY3Rpb24oZCkgew0KICBkICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSB4LCB5ID0geSwgeGVuZCA9IHhlbmQsIHllbmQgPSB5ZW5kLCBjb2xvdXIgPSBWYXJpYWJsZXMpKSArDQogICAgZ2VvbV9kYWdfcG9pbnQoKSArDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJJbmNsdWRlZCBpbiBtb2RlbCIgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVs0XSwgIk5vdCBpbmNsdWRlZCBpbiBtb2RlbCIgPSAiZ3JleTgwIikpICsNCiAgICBnZW9tX2RhZ190ZXh0KGNvbG9yID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIilbN10pICsNCiAgICBnZW9tX2RhZ19lZGdlcygpICsgDQogICAgdGhlbWVfZGFnKCkrDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KfQ0KDQoNCm9ic2VydmVyX2JpYXNfZGFnIDwtIGRhZ2lmeShFRiB+IFBFVyArIFBFTSArIFNCICsgVEYsDQogICAgICAgIFBFVyB+IEJULA0KICAgICAgICBQRU0gfiBCVCwNCiAgICAgICAgU0IgfiBQRVcgKyBQRU0sDQogICAgICAgbGFiZWxzID0gYygiVEYiID0gIlRydWVcbiBGb3JhZ2luZyIsIA0KICAgICAgICAgICAgICAgICAgIkVGIiA9ICJFc3RpbWF0ZWRcbiBGb3JhZ2luZyIsDQogICAgICAgICAgICAgICAgICAiUEVXIiA9ICJQcmlvclxuIEV4cGVjdGF0aW9uIE1lbiIsDQogICAgICAgICAgICAgICAgICAiUEVNIiA9ICJQcmlvclxuIEV4cGVjdGF0aW9uIFdvbWVuIiwNCiAgICAgICAgICAgICAgICAgICJCVCIgPSAiQmlhc1xuIFRyZWF0bWVudCIsDQogICAgICAgICAgICAgICAgICAiU0IiID0gIlNlbGVjdGlvblxuIEJpYXMiKSkgJT4lIA0KICB0aWR5X2RhZ2l0dHkoc2VlZCA9IDUpDQogIA0KICANCiBvYnNlcnZlcl9iaWFzX2RhZyA8LSBsZWZ0X2pvaW4ob2JzZXJ2ZXJfYmlhc19kYWckZGF0YSwgdGliYmxlKG5hbWUgPSBjKCJCVCIsICJFRiIsICJQRVciLCAiUEVNIiwgIlNCIiwgIlRGIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlcyA9IGMoIkluY2x1ZGVkIGluIG1vZGVsIiwgIkluY2x1ZGVkIGluIG1vZGVsIiwgIkluY2x1ZGVkIGluIG1vZGVsIiwgIkluY2x1ZGVkIGluIG1vZGVsIiwgIk5vdCBpbmNsdWRlZCBpbiBtb2RlbCIsICJOb3QgaW5jbHVkZWQgaW4gbW9kZWwiKSkpICU+JSANCiAgIA0KIGdnX3NpbXBsZV9kYWcoKQ0KDQoNCm9ic2VydmVyX2JpYXNfZGFnDQoNCmBgYA0KDQoqKkZpZ3VyZSAxKiouIEEgZGlyZWN0IGFjcnlsaWMgZGlhZ3JhbSBzaG93aW5nIHRoZSBmbG93IG9mIGNhdXNhdGlvbiBpbiBvdXIgYmlvbG9naWNhbCBzeXN0ZW0uIE91ciBiaWFzIHRyZWF0bWVudCAoQlQpIHdhcyBkZXNpZ25lZCB0byBhZmZlY3QgdGhlIHByaW9yIGV4cGVjdGF0aW9uIChQRSkgb2Ygb2JzZXJ2ZXIncywgYSBzdWJzZXQgb2Ygd2hpY2ggd2VyZSB3b21lbiAoUEVXKSwgd2hpbGUgdGhlIHJlbWFpbmluZyB3ZXJlIG1lbiAoUEVNKS4gUHJpb3IgZXhwZWN0YXRpb25zIG1heSBhZmZlY3QgdGhlIGVzdGltYXRlZCBsZXZlbCBvZiBmb3JhZ2luZyAoRUYpIGRpcmVjdGx5LCBvciBtb3JlIHNwZWNpZmljYWxseSB0aHJvdWdoIGJpYXNlZCBzZWxlY3Rpb24gb2YgcGFydGljdWxhciBmb3JhZ2VycyAoU0IpLiBFc3RpbWF0ZWQgZm9yYWdpbmcgaXMgYWxzbyBhZmZlY3RlZCBieSB0aGUgdHJ1ZSBsZXZlbCBvZiBmb3JhZ2luZyAoVEYpIGNhcnJpZWQgb3V0IGJ5IHRoZSBmbG9jayBvZiBwaWdlb25zIGluIHRoZSBmb290YWdlLiBXZSBoeXBvdGhlc2lzZWQgdGhhdCBfYSBwcmlvcmlfIGV4cGVjdGF0aW9ucyBvZiBvYnNlcnZlcidzIHdvdWxkIGFmZmVjdCB0aGVpciBmb3JhZ2luZyBlc3RpbWF0ZXMuIFRoZSBwYXRocyBjb25uZWN0aW5nIGNvbG91cmVkIHZhcmlhYmxlcyBzaG93IHRoYXQgdGhpcyBjYW4gYmUgdGVzdGVkIGJ5IG1vZGVsbGluZyB0aGUgZWZmZWN0IG9mIGJpYXMgdHJlYXRtZW50IG9uIGVzdGltYXRlZCBmb3JhZ2luZywgb3IgYWx0ZXJuYXRpdmVseSBieSBkaXJlY3RseSBtb2RlbGxpbmcgdGhlIGVmZmVjdCBvZiBwcmlvciBleHBlY3RhdGlvbiBvbiBlc3RpbWF0ZWQgZm9yYWdpbmcuIA0KDQokfiQNCg0KIyMjIE1vZGVsIDE6IGFsbG9jYXRlZCBwcmltZXINCg0KYGBge3J9DQoNCiMgRmlyc3QgbGV0J3MgbW9kZWwgdGhlIGVmZmVjdCBvZiBiaWFzIHRyZWF0bWVudCBvbiBmb3JhZ2luZyBlc3RpbWF0aW9uIA0KDQpmb3JhZ2luZ19tb2RlbF90cmVhdG1lbnQgPC0gYnJtKEZvcmFnaW5nX3Byb3AgfiAwICsgQmlhc190cmVhdG1lbnQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsIGZhbWlseSA9IEJldGEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBwaGkpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyID0gNjAwMCwgd2FybXVwID0gMjAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC44LCBtYXhfdHJlZWRlcHRoID0gMTApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQgPSAxLCBmaWxlID0gImZpdHMvZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50IikNCg0KZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50IDwtIGFkZF9jcml0ZXJpb24oZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50LCBjcml0ZXJpb24gPSAibG9vIiwgZmlsZSA9ICJmaXRzL2ZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCIpDQoNCmZvcmFnaW5nX21vZGVsX3RyZWF0bWVudA0KDQpmb3JhZ2luZ19tb2RlbF90cmVhdG1lbnRfZ2VuZGVyIDwtIGJybShGb3JhZ2luZ19wcm9wIH4gMCArIEdlbmRlciAqIEJpYXNfdHJlYXRtZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCBmYW1pbHkgPSBCZXRhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOCwgbWF4X3RyZWVkZXB0aCA9IDEwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkID0gMSwgZmlsZSA9ICJmaXRzL2ZvcmFnaW5nX21vZGVsX3RyZWF0bWVudF9nZW5kZXIiKQ0KDQpgYGANCg0KKipUYWJsZSBTMSoqLiBQb3N0ZXJpb3IgZXN0aW1hdGVzIG9mIHRoZSBwZXJjZW50YWdlIG9mIHBpZ2VvbiBmZWVkaW5nIHJhdGUsIHNwbGl0IGJ5IHRoZSBwcmltZXIgb2JzZXJ2ZXJzIHdlcmUgYWxsb2NhdGVkLg0KDQpgYGB7cn0NCm5ld19kYXRhIDwtIHRpYmJsZShCaWFzX3RyZWF0bWVudCA9IGMoIkh1bmdyeSIsICJTYXRpYXRlZCIpKQ0KDQpuZXdfZGF0YSAlPiUgDQogIGxlZnRfam9pbihkYXRhICU+JSBncm91cF9ieShCaWFzX3RyZWF0bWVudCkgJT4lIHN1bW1hcmlzZShgbiBvYnNlcnZlcnNgID0gbigpKSkgJT4lIA0KICBjYmluZChmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50LCBuZXdkYXRhID0gbmV3X2RhdGEsIHN1bW1hcnkgPSBUKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCB+IC54ICoxMDApLA0KICAgICAgICAgICAgICAgICBhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgDQogIHJlbmFtZSgiRXN0aW1hdGVkIHByb3BvcnRpb24gZm9yYWdpbmciID0gRXN0aW1hdGUsDQogICAgICAgICAiQmlhcyB0cmVhdG1lbnQiID0gQmlhc190cmVhdG1lbnQpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQoNCmBgYA0KDQpvciB0aGUgZ2VuZGVyIGFuYWx5c2lzIHZlcnNpb24NCg0KYGBge3J9DQojIGFkZCBnZW5kZXIgcHJlZGljdGlvbnMNCg0KbmV3X2RhdGFfZ2VuZGVyIDwtIGV4cGFuZF9ncmlkKEJpYXNfdHJlYXRtZW50ID0gYygiSHVuZ3J5IiwgIlNhdGlhdGVkIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZGVyID0gYygiV29tYW4iLCAiTWFuIikpDQoNCm5ld19kYXRhX2dlbmRlciAlPiUgDQogIGxlZnRfam9pbihkYXRhICU+JSBncm91cF9ieShHZW5kZXIsIEJpYXNfdHJlYXRtZW50KSAlPiUgc3VtbWFyaXNlKGBuIG9ic2VydmVyc2AgPSBuKCkpICU+JSANCiAgICAgICAgICB1bmdyb3VwKCkgJT4lIGZpbHRlcighaXMubmEoR2VuZGVyKSkpICU+JSANCiAgY2JpbmQoZml0dGVkKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudF9nZW5kZXIsIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXIsIHN1bW1hcnkgPSBUKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCB+IC54ICoxMDApLA0KICAgICAgICAgICAgICAgICBhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgDQogIHJlbmFtZSgiRXN0aW1hdGVkIHByb3BvcnRpb24gZm9yYWdpbmciID0gRXN0aW1hdGUsDQogICAgICAgICAiQmlhcyB0cmVhdG1lbnQiID0gQmlhc190cmVhdG1lbnQpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQpgYGANCg0KDQojIyMgTW9kZWwgMjogaW5kaWNhdGVkIGV4cGVjdGF0aW9uDQoNCmBgYHtyfQ0KDQojIGZpdCB0aGUgc2FtZSBtb2RlbCwgZXhjZXB0IHVzaW5nIHBhcnRpY2lwYW50IGV4cGVjdGF0aW9uIHJhdGhlciB0aGFuIGFsbG9jYXRlZCBiaWFzIHRyZWF0bWVudA0KDQpmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbiA8LSBicm0oRm9yYWdpbmdfcHJvcCB+IDAgKyBFeHBlY3RhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgZmFtaWx5ID0gQmV0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHBoaSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjgsIG1heF90cmVlZGVwdGggPSAxMCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9mb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbiIpDQoNCmZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uIDwtIGFkZF9jcml0ZXJpb24oZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb24sIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gImZpdHMvZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb24iKQ0KDQpmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbg0KDQpmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIgPC0gYnJtKEZvcmFnaW5nX3Byb3AgfiAwICsgR2VuZGVyICogRXhwZWN0YXRpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsIGZhbWlseSA9IEJldGEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBwaGkpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyID0gNjAwMCwgd2FybXVwID0gMjAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC44LCBtYXhfdHJlZWRlcHRoID0gMTApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQgPSAxLCBmaWxlID0gImZpdHMvZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyIikNCg0KYGBgDQoNCioqVGFibGUgUzIqKi4gUG9zdGVyaW9yIGVzdGltYXRlcyBvZiB0aGUgcGVyY2VudGFnZSBvZiBwaWdlb25zIGZvcmFnaW5nLCBzcGxpdCBieSB0aGUgYWN0dWFsIGV4cGVjdGF0aW9uIG9mIG9ic2VydmVycy4NCg0KYGBge3J9DQoNCm5ld19kYXRhXzIgPC0gdGliYmxlKEV4cGVjdGF0aW9uID0gYygiSHVuZ3J5IiwgIlNhdGlhdGVkIikpDQoNCm5ld19kYXRhXzIgJT4lIA0KICAgbGVmdF9qb2luKGRhdGEgJT4lIGdyb3VwX2J5KEV4cGVjdGF0aW9uKSAlPiUgc3VtbWFyaXNlKGBuIG9ic2VydmVyc2AgPSBuKCkpKSAlPiUgDQogIGNiaW5kKGZpdHRlZChmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbiwgbmV3ZGF0YSA9IG5ld19kYXRhXzIsIHN1bW1hcnkgPSBUKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCB+IC54ICoxMDApLA0KICAgICAgICAgICAgICAgICBhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgIA0KICByZW5hbWUoIkVzdGltYXRlZCBwcm9wb3J0aW9uIGZvcmFnaW5nIiA9IEVzdGltYXRlLA0KICAgICAgICAgIkluZGljYXRlZCBleHBlY3RhdGlvbiIgPSBFeHBlY3RhdGlvbikgJT4lIA0KICBwYW5kZXIoc3BsaXQuY2VsbCA9IDIwLCBzcGxpdC50YWJsZSA9IEluZikNCg0KYGBgDQoNCnRoZSBnZW5kZXIgYW5hbHlzaXMgdmVyc2lvbg0KDQpgYGB7cn0NCiMgYWRkIGdlbmRlciBwcmVkaWN0aW9ucw0KDQpuZXdfZGF0YV9nZW5kZXJfMiA8LSBleHBhbmRfZ3JpZChFeHBlY3RhdGlvbiA9IGMoIkh1bmdyeSIsICJTYXRpYXRlZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmRlciA9IGMoIldvbWFuIiwgIk1hbiIpKQ0KDQpuZXdfZGF0YV9nZW5kZXJfMiAlPiUgDQogIGxlZnRfam9pbihkYXRhICU+JSBncm91cF9ieShFeHBlY3RhdGlvbiwgR2VuZGVyKSAlPiUgc3VtbWFyaXNlKGBuIG9ic2VydmVyc2AgPSBuKCkpICU+JSANCiAgICAgICAgICB1bmdyb3VwKCkgJT4lIGZpbHRlcighaXMubmEoR2VuZGVyKSkpICU+JQ0KICBjYmluZChmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IFQpICU+JSANCiAgICAgICAgICBhc190aWJibGUoKSAlPiUgDQogICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIH4gLnggKjEwMCksDQogICAgICAgICAgICAgICAgIGFjcm9zcygxOjQsIHJvdW5kLCAyKSkpICU+JSANCiAgcmVuYW1lKCJFc3RpbWF0ZWQgcHJvcG9ydGlvbiBmb3JhZ2luZyIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICJJbmRpY2F0ZWQgZXhwZWN0YXRpb24iID0gRXhwZWN0YXRpb24pICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQpgYGANCg0KDQokfiQNCg0KIyMgQnVpbGQgRmlndXJlIDJhLWQNCg0KJH4kDQoNCioqR2V0IHBvc3RlcmlvciBtZWFucyBhbmQgZGlmZmVyZW5jZSBjb250cmFzdHMqKg0KDQpgYGB7cn0NCg0KIyB0cmVhdG1lbnQgbW9kZWwNCg0KZHJhd3NfdHJlYXRtZW50IDwtDQogIGFzX2RyYXdzX2RmKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCkgJT4lIA0KICBtdXRhdGUoSHVuZ3J5ID0gaW52X2xvZ2l0X3NjYWxlZChiX0JpYXNfdHJlYXRtZW50SHVuZ3J5KSAqMTAwLA0KICAgICAgICAgU2F0aWF0ZWQgPSBpbnZfbG9naXRfc2NhbGVkKGJfQmlhc190cmVhdG1lbnRTYXRpYXRlZCkqMTAwLA0KICAgICAgICAgZGlmZl9jb250cmFzdCA9IChIdW5ncnkgLSBTYXRpYXRlZCkpICU+JSANCiAgc2VsZWN0KEh1bmdyeSwgU2F0aWF0ZWQsIGRpZmZfY29udHJhc3QpICU+JSANCiAgcGl2b3RfbG9uZ2VyKG5hbWVzX3RvID0gIlRyZWF0bWVudCIsIHZhbHVlc190byA9ICJQb3N0ZXJpb3JfZXN0aW1hdGUiLCBjb2xzID0gMTozKSAlPiUgDQogIG11dGF0ZShQcmVkaWN0b3IgPSAiQWxsb2NhdGVkIHByaW1lciIpDQoNCnAyIDwtIA0KICBkcmF3c190cmVhdG1lbnQgJT4lIA0KICBmaWx0ZXIoVHJlYXRtZW50ICE9ICJkaWZmX2NvbnRyYXN0IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKHlsaW0gPSBjKDI1LCA1NSkpICsNCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLCAwLCAxKSkgKw0KICB4bGFiKCJBbGxvY2F0ZWQgcHJpbWVyIikgKw0KICB5bGFiKCJFc3RpbWF0ZWQgJSBwaWdlb25zIGZvcmFnaW5nIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQ0KDQpwMyA8LQ0KICBkcmF3c190cmVhdG1lbnQgJT4lIA0KICBmaWx0ZXIoVHJlYXRtZW50ID09ICJkaWZmX2NvbnRyYXN0IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsIHNjYWxlID0wLjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIilbNF0pICsNCiAgY29vcmRfZmxpcCh5bGltID0gYygtMjAsIDIwKSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuNzUpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYihOVUxMKSArDQogIHlsYWIoIkh1bmdyeSAtIFNhdGlhdGVkIGRpZmZlcmVuY2VcbmNvbnRyYXN0ICglIHBvaW50cykiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCg0KIyBleHBlY3RhdGlvbiBtb2RlbA0KDQpkcmF3c19leHBlY3RhdGlvbiA8LQ0KICBhc19kcmF3c19kZihmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbikgJT4lIA0KICBtdXRhdGUoSHVuZ3J5ID0gaW52X2xvZ2l0X3NjYWxlZChiX0V4cGVjdGF0aW9uSHVuZ3J5KSAqMTAwLA0KICAgICAgICAgU2F0aWF0ZWQgPSBpbnZfbG9naXRfc2NhbGVkKGJfRXhwZWN0YXRpb25TYXRpYXRlZCkqMTAwLA0KICAgICAgICAgZGlmZl9jb250cmFzdCA9IChIdW5ncnkgLSBTYXRpYXRlZCkpICU+JSANCiAgc2VsZWN0KEh1bmdyeSwgU2F0aWF0ZWQsIGRpZmZfY29udHJhc3QpICU+JSANCiAgcGl2b3RfbG9uZ2VyKG5hbWVzX3RvID0gIlRyZWF0bWVudCIsIHZhbHVlc190byA9ICJQb3N0ZXJpb3JfZXN0aW1hdGUiLCBjb2xzID0gMTozKSAlPiUgDQogIG11dGF0ZShQcmVkaWN0b3IgPSAiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIikNCg0KcDQgPC0NCiAgZHJhd3NfZXhwZWN0YXRpb24gJT4lIA0KICBmaWx0ZXIoVHJlYXRtZW50ICE9ICJkaWZmX2NvbnRyYXN0IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCh5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYigiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIikgKw0KICB5bGFiKCJFc3RpbWF0ZWQgJSBwaWdlb25zIGZvcmFnaW5nIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQ0KDQpwNSA8LQ0KICBkcmF3c19leHBlY3RhdGlvbiAlPiUgDQogIGZpbHRlcihUcmVhdG1lbnQgPT0gImRpZmZfY29udHJhc3QiKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsIHNjYWxlID0wLjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIilbNF0pICsNCiAgY29vcmRfZmxpcCh5bGltID0gYygtMjAsIDIwKSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuNzUpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYihOVUxMKSArDQogIHlsYWIoIkh1bmdyeSAtIFNhdGlhdGVkIGRpZmZlcmVuY2VcbmNvbnRyYXN0ICglIHBvaW50cykiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCmBgYA0KDQpOb3cgYnVpbGQgdGhlIHBsb3RzIGZvciB0aGUgbW9kZWxzIHRoYXQgaW5jbHVkZSBnZW5kZXINCg0KYGBge3J9DQoNCiMgdHJlYXRtZW50IG1vZGVsDQoNCmdlbmRlcl90cmVhdG1lbnRfZHJhd3MgPC0NCiAgZml0dGVkKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudF9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlciwgc3VtbWFyeSA9IEYpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjQsIG5hbWVzX3RvID0gIkdyb3VwIiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIpICU+JSANCiAgc2VwYXJhdGUoc2VwID0gIl8iLCBjb2wgPSBHcm91cCwgaW50byA9IGMoIlRyZWF0bWVudCIsICJHZW5kZXIiKSkgJT4lDQogIG11dGF0ZShQb3N0ZXJpb3JfZXN0aW1hdGUgPSBQb3N0ZXJpb3JfZXN0aW1hdGUqMTAwKSANCiAgDQpjYWxjdWxhdGVfYWxsX3RoZV9kaWZmcyA8LQ0KICBmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50X2dlbmRlciwgDQogICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGFfZ2VuZGVyLCBzdW1tYXJ5ID0gRikgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tYW4gPSBWMSwgSHVuZ3J5X01hbiA9IFYyLCBTYXRpYXRlZF9Xb21hbiA9IFYzLCBTYXRpYXRlZF9NYW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tYW5faF9zX2RpZmYgPSBIdW5ncnlfV29tYW4gLSBTYXRpYXRlZF9Xb21hbiwNCiAgICAgICAgIE1hbl9oX3NfZGlmZiA9IEh1bmdyeV9NYW4gLSBTYXRpYXRlZF9NYW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21hbl9oX3NfZGlmZiAtIE1hbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tYW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1hbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKSAlPiUgDQogIG11dGF0ZShwb3N0ZXJpb3JfZGlmZiA9IHBvc3Rlcmlvcl9kaWZmKjEwMCkNCiAgDQoNCmdwMSA8LSANCiAgZ2VuZGVyX3RyZWF0bWVudF9kcmF3cyAlPiUgDQogIGdncGxvdChhZXMoeCA9IEdlbmRlciwgeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICAgc3RhdF9zbGFiKGFscGhhID0gMC44LCBzaGFwZSA9IDIxLCBhZXMoZmlsbCA9IFRyZWF0bWVudCkpICsNCiAgI3N0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICMgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICMgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LA0KICAgIyAgICAgICAgICAgIGZpbGwgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KVsyXSkgKw0KICAjc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAxMClbNF0sIG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDEwKVs2XSkpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgbGFicyh4ID0gIkdlbmRlciIsIHkgPSAiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIsIGZpbGwgPSAiQWxsb2NhdGVkXG5wcmltZXIiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpDQoNCg0KDQpncDIgPC0NCiAgY2FsY3VsYXRlX2FsbF90aGVfZGlmZnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkaWZmX2NvbnRyYXN0LCB5ID0gcG9zdGVyaW9yX2RpZmYpKSArIA0KICAgICNzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gR2VuZGVyKSkgKw0KICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsDQogICAgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzVdKSArDQogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkRpZmZlcmVuY2UgY29udHJhc3QiKSArDQogIHlsYWIoIiUgcG9pbnRzIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQojIGV4cGVjdGF0aW9uIG1vZGVsDQoNCmdlbmRlcl9leHBlY3RhdGlvbl9kcmF3cyA8LQ0KICBmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IEYpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjQsIG5hbWVzX3RvID0gIkdyb3VwIiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIpICU+JSANCiAgc2VwYXJhdGUoc2VwID0gIl8iLCBjb2wgPSBHcm91cCwgaW50byA9IGMoIlRyZWF0bWVudCIsICJHZW5kZXIiKSkgJT4lDQogIG11dGF0ZShQb3N0ZXJpb3JfZXN0aW1hdGUgPSBQb3N0ZXJpb3JfZXN0aW1hdGUqMTAwKSANCiAgDQpjYWxjdWxhdGVfYWxsX3RoZV9kaWZmc18yIDwtDQogIGZpdHRlZChmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlcl8yLCBzdW1tYXJ5ID0gRikgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tYW4gPSBWMSwgSHVuZ3J5X01hbiA9IFYyLCBTYXRpYXRlZF9Xb21hbiA9IFYzLCBTYXRpYXRlZF9NYW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tYW5faF9zX2RpZmYgPSBIdW5ncnlfV29tYW4gLSBTYXRpYXRlZF9Xb21hbiwNCiAgICAgICAgIE1hbl9oX3NfZGlmZiA9IEh1bmdyeV9NYW4gLSBTYXRpYXRlZF9NYW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21hbl9oX3NfZGlmZiAtIE1hbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tYW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1hbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKSAlPiUgDQogIG11dGF0ZShwb3N0ZXJpb3JfZGlmZiA9IHBvc3Rlcmlvcl9kaWZmKjEwMCkNCg0KZ3AzIDwtIA0KICBnZW5kZXJfZXhwZWN0YXRpb25fZHJhd3MgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBHZW5kZXIsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgIHN0YXRfc2xhYihhbHBoYSA9IDAuOSwgc2hhcGUgPSAyMSwgYWVzKGZpbGwgPSBUcmVhdG1lbnQpKSArDQogICNzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAjICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAjICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwNCiAgICMgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSlbMl0pICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgbGFicyh4ID0gIkdlbmRlciIsIHkgPSAiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIsIGZpbGwgPSAiSW5kaWNhdGVkXG5leHBlY3RhdGlvbiIpICsNCiAgdGhlbWVfYncoKSArIA0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQ0KDQoNCg0KZ3A0IDwtDQogIGNhbGN1bGF0ZV9hbGxfdGhlX2RpZmZzXzIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkaWZmX2NvbnRyYXN0LCB5ID0gcG9zdGVyaW9yX2RpZmYpKSArIA0KICAgICNzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gR2VuZGVyKSkgKw0KICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsDQogICAgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzVdKSArDQogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkRpZmZlcmVuY2UgY29udHJhc3QiKSArDQogIHlsYWIoIiUgcG9pbnRzIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQpgYGANCg0KJH4kDQoNCiMgUXVlc3Rpb24gMjogaXMgZXN0aW1hdGlvbiBvZiBmZWVkaW5nIHJhdGUgYWZmZWN0ZWQgYnkgYmlhcyBtYW5pcHVsYXRpb25zPw0KDQokfiQNCg0KV2UgYXNrZWQgb2JzZXJ2ZXJzIHRvIGNvdW50IHRoZSBudW1iZXIgb2YgcGVja3Mgb2YgdGhlIGdyb3VuZCB0aGF0IGEgc2VsZWN0ZWQgcGlnZW9uIG1hZGUgb3ZlciBhIDEgbWludXRlIHBlcmlvZC4gV2UgdXNlIHRoZSBudW1iZXIgb2YgcGVja3MgdGhhdCBvY2N1ciBhcyBhIG1lYXN1cmUgb2YgZmVlZGluZyByYXRlLg0KDQpXZSBmaXJzdCBlc3RpbWF0ZWQgYSBiYXNlbGluZSBwZWNrIHJhdGUgYnkgb2JzZXJ2aW5nIDM1IHBpZ2VvbnMuIFRvIHNlbGVjdCB0aGUgcGlnZW9ucyB3ZSBvYnNlcnZlZCwgd2Ugc3BsaXQgYSBzdGlsbCBpbWFnZSBvZiB0aGUgZm9yYWdpbmcgdmlkZW8gKHRha2VuIGF0IHRpbWUgemVybykgaW50byBhIDQzIHggMjEgY2VsbCBncmlkLiBGcm9tIHRoZSAxMjIgY2VsbHMgdGhhdCBjb250YWluZWQgcGlnZW9ucywgNDAgd2VyZSBjaG9zZW4gYnkgcmFuZG9tIG51bWJlciBnZW5lcmF0aW9uIChzZWUgY29kZSBjaHVuayBiZWxvdykuIEluIHRoZSBldmVudCB0aGF0IG11bHRpcGxlIHBpZ2VvbnMgd2VyZSBwcmVzZW50IGluIHRoZSBjZWxsLCB3ZSBzZWxlY3RlZCB0aGUgbW9zdCBwcm9taW5lbnQgdG8gb2JzZXJ2ZS4gRml2ZSBvYnNlcnZhdGlvbnMgd2VyZSBkaXNjYXJkZWQgLSB0aHJlZSBkdWUgdG8gb3ZlcmxhcCBvZiB0aGUgc2FtZSBwaWdlb24gYmV0d2VlbiBjZWxscyB0aGF0IHdlcmUgc2VsZWN0ZWQgYnkgdGhlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLCBhbmQgdHdvIG1vcmUgYXMgdGhlIHBpZ2VvbnMgbGVmdCB0aGUgZmllbGQgb2YgdmlldyBkdXJpbmcgdGhlIHZpZGVvIGFuZCBjb3VsZCBubyBsb25nZXIgYmUgdHJhY2tlZC4gDQoNCg0KYGBge3J9DQojIGN1cmx5IGJyYWNrZXRzIHJ1biBhbGwgbGluZXMgaW5jbHVkZWQgd2l0aGluIHRoZW0NCg0Ke3NldC5zZWVkKDEpICMgc28gdGhhdCBzYW1wbGUgcHJvZHVjZXMgYSByZXByb2R1Y2libGUgc2VxdWVuY2UgDQogIHNhbXBsZSgxOjEyMiwgNDAsIHJlcGxhY2UgPSBGQUxTRSl9DQpgYGANCg0KVGhlIHNlbGVjdGVkIHBpZ2VvbnMgZm9yIGJhc2VsaW5lIG9ic2VydmF0aW9uIGFyZSBzaG93biBpbiB0aGUgaW1hZ2UgYmVsb3cNCg0KYGBge3J9DQppbWcgPC0gcmVhZFBORygicGlnZW9uX3NlbGVjdGlvbi5wbmciKQ0KIGdyaWQucmFzdGVyKGltZykNCmBgYA0KDQoNCiR+JA0KDQojIyBFc3RpbWF0aW5nIGJhc2VsaW5lIGZlZWRpbmcgcmF0ZQ0KDQokfiQNCg0KKipMb2FkIGluIHRoZSBkYXRhKioNCg0KYGBge3J9DQoNCmJhc2VsaW5lX2RhdGEgPC0gcmVhZF9jc3YoImRhdGEvYmFzZWxpbmVfcGVja19kYXRhLmNzdiIpICU+JSANCiAgc2VsZWN0KDE6NSkgJT4lICAjIHJlbW92ZSB0aGUgY29tbWVudHMgY29sdW1uDQogIHBpdm90X2xvbmdlcihjb2xzID0gNDo1LCBuYW1lc190byA9ICJPYnNlcnZhdGlvbiIsIHZhbHVlc190byA9ICJQZWNrX3JhdGUiKSAlPiUgDQogIG11dGF0ZShJRCA9IGFzLmZhY3RvcihJRCksDQogICAgICAgICBPYnNlcnZhdGlvbiA9IHN0cl9yZW1vdmUoT2JzZXJ2YXRpb24sICJQZWNrX2NvdW50XyIpKSAlPiUgDQogIHJlbmFtZShQaWdlb25fSUQgPSBJRCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKFBlY2tfcmF0ZSkpDQoNCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpew0KICBkYXRhdGFibGUoDQogICAgZGYsIHJvd25hbWVzPUZBTFNFLA0KICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsDQogICAgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgICJCdXR0b25zIiksDQogICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgIGRlZmVyUmVuZGVyPVRSVUUsDQogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLA0KICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwNCiAgICAgIGJ1dHRvbnMgPQ0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KA0KICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLA0KICAgICAgICAgIHBhZ2VTaXplID0gJ0E0JywNCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLA0KICAgICAgICAgIGZpbGVuYW1lID0gJ2Jhc2VsaW5lX2RhdGFzZXQnKSksDQogICAgICBwYWdlTGVuZ3RoID0gNzgNCiAgICApDQogICkNCn0NCg0KDQpteV9kYXRhX3RhYmxlKGJhc2VsaW5lX2RhdGEpDQoNCmBgYA0KDQotIGBYYCBhbmQgYFlgIHJlcHJlc2VudCBncmlkIGNvb3JkaW5hdGVzLg0KDQotIGBQaWdlb25fSURgIGlkZW50aWZpZXMgYSBzcGVjaWZpYyBwaWdlb24NCg0KLSBgT2JzZXJ2YXRpb25gIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgd2FzIHRoZSBmaXJzdCBvciBzZWNvbmQgc2NvcmluZyBmb3IgYSBzaW5nbGUgcGlnZW9uLiBXZSBzY29yZWQgZWFjaCBwaWdlb24gdHdpY2UgYXMgZGlzdGFudCBwaWdlb25zIHdlcmUgZGlmZmljdWx0IHRvIG9ic2VydmUgYW5kIHRvIGVuc3VyZSB0aGF0IHRoZSBjb3JyZWN0IHBpZ2VvbiB3YXMgdHJhY2tlZCB0aHJvdWdob3V0IHRoZSBtaW51dGUgb2Ygb2JzZXJ2YXRpb24uDQoNCi0gYFBlY2tfcmF0ZWAgaXMgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgZ3JvdW5kIHdhcyBwZWNrZWQgb3ZlciBhIG1pbnV0ZSBvZiBvYnNlcnZhdGlvbi4NCg0KJH4kDQoNCioqRml0IGEgc2ltcGxlIG1vZGVsIHRvIGVzdGltYXRlIG1lZGlhbiBwZWNrIHJhdGUqKg0KDQpgYGB7cn0NCg0KYmFzZWxpbmVfcGVja19tb2RlbF96aSA8LQ0KICBicm0oUGVja19yYXRlIH4gMSArICgxfFBpZ2Vvbl9JRCksDQogICAgICBmYW1pbHkgPSB6ZXJvX2luZmxhdGVkX25lZ2Jpbm9taWFsKCksIGRhdGEgPSBiYXNlbGluZV9kYXRhLA0KICAgICAgcHJpb3IgPSBjKCBwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBJbnRlcmNlcHQpLA0KICAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCksDQogICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNoYXBlKSwNCiAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gemkpKSwNCiAgICAgIGNoYWlucyA9IDQsIGNvcmVzID0gNCwgd2FybXVwID0gMjAwMCwgaXRlciA9IDYwMDAsDQogICAgICBmaWxlID0gImZpdHMvYmFzZWxpbmVfcGVja19tb2RlbCIpDQoNCiMgd3JhbmdsZSB0aGUgb3V0cHV0DQoNCmJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgPC0NCiAgYmFzZWxpbmVfcGVja19tb2RlbF96aSAlPiUgDQogIGFzX2RyYXdzX2RmKCkgJT4lIA0KICBtdXRhdGUoQmFzZWxpbmVfZXN0aW1hdGUgPSBleHAoYl9JbnRlcmNlcHQpLA0KICAgICAgICAgcGVja19yYXRlX3NkID0gZXhwKHNkX1BpZ2Vvbl9JRF9fSW50ZXJjZXB0KSkgJT4lIA0KICBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUsIHBlY2tfcmF0ZV9zZCkNCg0KYmFzZWxpbmVfZGF0YSAlPiUgDQogIGRpc3RpbmN0KFBpZ2Vvbl9JRCkgJT4lIA0KICBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBsZW5ndGgoUGlnZW9uX0lEKSkgJT4lDQogIGJpbmRfY29scygNCmZpdHRlZChiYXNlbGluZV9wZWNrX21vZGVsX3ppLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lDQogICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSAlPiUgDQogIHJlbmFtZShgQmFzZWxpbmUgbWVkaWFuIHBlY2sgcmF0ZSAvIHBlciBtaW5gID0gRXN0aW1hdGUpKSAlPiUNCiAgcGFuZGVyKCkNCg0KYGBgDQoNCiR+JA0KDQojIyBFeHBlcmltZW50YWwgZGF0YQ0KDQokfiQNCg0KIyMjIEV4cGxvcmluZyBhbGxvY2F0aW9uIHZlcnN1cyBleHBlY3RhdGlvbiAyLjAgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KJH4kDQoNCk9uY2UgYWdhaW4sIHdlIGV4cGVjdCB0aGF0IGF0dGVudGlvbiBwYWlkIHRvIGFuZC9vciBjb21wcmVoZW5zaW9uIG9mIHRoZSBwcmltZXIgc3RhdGVtZW50IGhhcyBhIGxhcmdlIGVmZmVjdCBvbiBvYnNlcnZlcnMnIHBlcmNlcHRpb24gb2YgcGlnZW9uIGZvcmFnaW5nLiANCg0KTGV0cyBhZ2FpbiBmaXQgb3VyIHR3byBtb2RlbHM6DQoNCjEuIGEgbW9kZWwgd2l0aCBhbGxvY2F0ZWQgcHJpbWVyIChgQmlhc190cmVhdG1lbnRgKSBhcyB0aGUgcHJlZGljdG9yIHZhcmlhYmxlIA0KDQoyLiBhIG1vZGVsIHdpdGggaW5kaWNhdGVkIGh1bmdlciBleHBlY3RhdGlvbiAoYEV4cGVjdGF0aW9uYCkgYXMgdGhlIHByZWRpY3RvciB2YXJpYWJsZQ0KDQokfiQNCg0KIyMjIyBNb2RlbCAxOiBhbGxvY2F0ZWQgcHJpbWVyDQoNCmBgYHtyfQ0KDQojIEZpcnN0IGxldCdzIG1vZGVsIHRoZSBlZmZlY3Qgb2YgYmlhcyB0cmVhdG1lbnQgb24gcGVjayByYXRlDQoNCnBlY2tfbW9kZWxfdHJlYXRtZW50IDwtIA0KICBicm0oUGVja19yYXRlIH4gMCArIEJpYXNfdHJlYXRtZW50ICsgKDF8T2JzZXJ2ZXJfSUQpLA0KICAgICAgZGF0YSA9IGRhdGFfcGVjaywgZmFtaWx5ID0gbmVnYmlub21pYWwsDQogICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gc2QpKSwNCiAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOSwgbWF4X3RyZWVkZXB0aCA9IDEyKSwNCiAgICAgIHNlZWQgPSAxLCBmaWxlID0gImZpdHMvcGVja19tb2RlbF90cmVhdG1lbnQiKQ0KDQpwZWNrX21vZGVsX3RyZWF0bWVudCA8LSBhZGRfY3JpdGVyaW9uKHBlY2tfbW9kZWxfdHJlYXRtZW50LCBjcml0ZXJpb24gPSAibG9vIiwgZmlsZSA9ICJmaXRzL3BlY2tfbW9kZWxfdHJlYXRtZW50IikNCiAgDQpwZWNrX21vZGVsX3RyZWF0bWVudA0KDQpwZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIgPC0gDQogIGJybShQZWNrX3JhdGUgfiAwICsgR2VuZGVyICogQmlhc190cmVhdG1lbnQgKyAoMXxPYnNlcnZlcl9JRCksDQogICAgICBkYXRhID0gZGF0YV9wZWNrLCBmYW1pbHkgPSBuZWdiaW5vbWlhbCwNCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLA0KICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9wZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIiKQ0KYGBgDQoNCioqVGFibGUgUzMqKi4gVGhlIGVzdGltYXRlZCBwZWNrIHJhdGUgb2YgZm9yYWdpbmcgcGlnZW9ucywgc3BsaXQgYnkgdGhlIHByaW1lciBvYnNlcnZlcnMgd2VyZSBhbGxvY2F0ZWQuDQoNCmBgYHtyfQ0KbmV3X2RhdGEgJT4lIA0KICBiaW5kX2NvbHMoZml0dGVkKHBlY2tfbW9kZWxfdHJlYXRtZW50LCBuZXdkYXRhID0gbmV3X2RhdGEsIHN1bW1hcnkgPSBULCByZV9mb3JtdWxhID0gTkEpICU+JSANCiAgICAgICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSkgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YV9wZWNrICU+JSBncm91cF9ieShCaWFzX3RyZWF0bWVudCkgJT4lIA0KICAgICAgICAgICAgICBkaXN0aW5jdChPYnNlcnZlcl9JRCkgJT4lIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IG4oKSkpICU+JSANCiAgcmVuYW1lKCJFc3RpbWF0ZWQgcGVjayByYXRlIiA9IEVzdGltYXRlLA0KICAgICAgICAgIkJpYXMgdHJlYXRtZW50IiA9IEJpYXNfdHJlYXRtZW50KSAlPiUgDQogIGJpbmRfcm93cyhmaXR0ZWQoYmFzZWxpbmVfcGVja19tb2RlbF96aSwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUNCiAgICAgICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkgJT4lIA0KICAgICAgICAgICAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGBCaWFzIHRyZWF0bWVudGAgPSAiQmFzZWxpbmUiKSAlPiUgDQogICAgICAgICAgICAgIGJpbmRfY29scyhiYXNlbGluZV9kYXRhICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGluY3QoUGlnZW9uX0lEKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IGxlbmd0aChQaWdlb25fSUQpKSkpICU+JSANCiAgc2VsZWN0KGBCaWFzIHRyZWF0bWVudGAsIGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgLCBldmVyeXRoaW5nKCkpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQoNCmBgYA0KDQphZGQgdGhlIGdlbmRlciBzcGVjaWZpYyBlc3RpbWF0ZXMNCg0KYGBge3J9DQojIGFkZCB0aGUgZ2VuZGVyIHRhYmxlDQoNCm5ld19kYXRhX2dlbmRlciAlPiUgDQogIGJpbmRfY29scyhmaXR0ZWQocGVja19tb2RlbF90cmVhdG1lbnRfZ2VuZGVyLCANCiAgICAgICAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXIsIHN1bW1hcnkgPSBULCByZV9mb3JtdWxhID0gTkEpICU+JSANCiAgICAgICAgICBhc190aWJibGUoKSAlPiUgDQogICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkpICU+JSANCiAgbGVmdF9qb2luKGRhdGFfcGVjayAlPiUgZ3JvdXBfYnkoQmlhc190cmVhdG1lbnQsIEdlbmRlcikgJT4lIA0KICAgICAgICAgICAgICAgZGlzdGluY3QoT2JzZXJ2ZXJfSUQpICU+JSBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBuKCkpKSAlPiUgDQogICAgcmVuYW1lKCJFc3RpbWF0ZWQgcGVjayByYXRlIiA9IEVzdGltYXRlLA0KICAgICAgICAgIkJpYXMgdHJlYXRtZW50IiA9IEJpYXNfdHJlYXRtZW50KSAlPiUgDQogIGJpbmRfcm93cyhmaXR0ZWQoYmFzZWxpbmVfcGVja19tb2RlbF96aSwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUNCiAgICAgICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkgJT4lIA0KICAgICAgICAgICAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGBCaWFzIHRyZWF0bWVudGAgPSAiQmFzZWxpbmUiLCBHZW5kZXIgPSAiLSIpICU+JSANCiAgICAgICAgICAgICAgYmluZF9jb2xzKGJhc2VsaW5lX2RhdGEgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0aW5jdChQaWdlb25fSUQpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgID0gbGVuZ3RoKFBpZ2Vvbl9JRCkpKSkgJT4lIA0KICBzZWxlY3QoYEJpYXMgdHJlYXRtZW50YCwgYG4gcGlnZW9ucyBvYnNlcnZlZGAsIGV2ZXJ5dGhpbmcoKSkgJT4lIA0KICBwYW5kZXIoc3BsaXQuY2VsbCA9IDIwLCBzcGxpdC50YWJsZSA9IEluZikNCmBgYA0KDQoNCiMjIyMgTW9kZWwgMjogSW5kaWNhdGVkIGV4cGVjdGF0aW9uDQoNCmBgYHtyfQ0KDQojIGZpdCB0aGUgc2FtZSBtb2RlbCwgZXhjZXB0IHVzaW5nIHBhcnRpY2lwYW50IGV4cGVjdGF0aW9uIHJhdGhlciB0aGFuIGFsbG9jYXRlZCBiaWFzIHRyZWF0bWVudA0KDQpwZWNrX21vZGVsX2V4cGVjdGF0aW9uIDwtIGJybShQZWNrX3JhdGUgfiAwICsgRXhwZWN0YXRpb24gKyAoMXxPYnNlcnZlcl9JRCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGFfcGVjaywgZmFtaWx5ID0gbmVnYmlub21pYWwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IGIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk1LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQgPSAxLCBmaWxlID0gImZpdHMvcGVja19tb2RlbF9leHBlY3RhdGlvbiIpDQoNCnBlY2tfbW9kZWxfZXhwZWN0YXRpb24gPC0gYWRkX2NyaXRlcmlvbihwZWNrX21vZGVsX2V4cGVjdGF0aW9uLCBjcml0ZXJpb24gPSAibG9vIiwgZmlsZSA9ICJmaXRzL3BlY2tfbW9kZWxfZXhwZWN0YXRpb24iKQ0KDQoNCnBlY2tfbW9kZWxfZXhwZWN0YXRpb24NCiNsb29fY29tcGFyZShwZWNrX21vZGVsX3RyZWF0bWVudCwgcGVja19tb2RlbF9leHBlY3RhdGlvbikNCg0KcGVja19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIgPC0gYnJtKFBlY2tfcmF0ZSB+IDAgKyBHZW5kZXIgKiBFeHBlY3RhdGlvbiArICgxfE9ic2VydmVyX0lEKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9wZWNrLCBmYW1pbHkgPSBuZWdiaW5vbWlhbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTUsIG1heF90cmVlZGVwdGggPSAxMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9wZWNrX21vZGVsX2V4cGVjdGF0aW9uX2dlbmRlciIpDQpgYGANCg0KKipUYWJsZSBTNCoqLiBUaGUgZXN0aW1hdGVkIHBlY2sgcmF0ZSBvZiBmb3JhZ2luZyBwaWdlb25zLCBzcGxpdCBieSB0aGUgaW5kaWNhdGVkIGV4cGVjdGF0aW9uIG9mIHRoZSBvYnNlcnZlcnMuDQoNCmBgYHtyfQ0KDQpuZXdfZGF0YV8yICU+JSANCiAgYmluZF9jb2xzKGZpdHRlZChwZWNrX21vZGVsX2V4cGVjdGF0aW9uLCBuZXdkYXRhID0gbmV3X2RhdGFfMiwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUgDQogICAgICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgDQogIGxlZnRfam9pbihkYXRhX3BlY2sgJT4lIGdyb3VwX2J5KEV4cGVjdGF0aW9uKSAlPiUgDQogICAgICAgICAgICAgIGRpc3RpbmN0KE9ic2VydmVyX0lEKSAlPiUgc3VtbWFyaXNlKGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgID0gbigpKSkgJT4lIA0KICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUsDQogICAgICAgICAiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIiA9IEV4cGVjdGF0aW9uKSAlPiUgDQogIGJpbmRfcm93cyhmaXR0ZWQoYmFzZWxpbmVfcGVja19tb2RlbF96aSwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUNCiAgICAgICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkgJT4lIA0KICAgICAgICAgICAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGBJbmRpY2F0ZWQgZXhwZWN0YXRpb25gID0gIkJhc2VsaW5lIikgJT4lIA0KICAgICAgICAgICAgICBiaW5kX2NvbHMoYmFzZWxpbmVfZGF0YSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RpbmN0KFBpZ2Vvbl9JRCkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBsZW5ndGgoUGlnZW9uX0lEKSkpKSAlPiUgDQogIHNlbGVjdChgSW5kaWNhdGVkIGV4cGVjdGF0aW9uYCwgYG4gcGlnZW9ucyBvYnNlcnZlZGAsIGV2ZXJ5dGhpbmcoKSkgJT4lIA0KICBwYW5kZXIoc3BsaXQuY2VsbCA9IDIwLCBzcGxpdC50YWJsZSA9IEluZikNCg0KYGBgDQoNCmFkZCB0aGUgZ2VuZGVyIHNwZWNpZmljIGVzdGltYXRlcw0KDQpgYGB7cn0NCg0KIyBhZGQgdGhlIGdlbmRlciB0YWJsZQ0KDQpuZXdfZGF0YV9nZW5kZXJfMiAlPiUgDQogIGJpbmRfY29scyhmaXR0ZWQocGVja19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIsIA0KICAgICAgICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlcl8yLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgDQogIGxlZnRfam9pbihkYXRhX3BlY2sgJT4lIGdyb3VwX2J5KEV4cGVjdGF0aW9uLCBHZW5kZXIpICU+JSANCiAgICAgICAgICAgICAgIGRpc3RpbmN0KE9ic2VydmVyX0lEKSAlPiUgc3VtbWFyaXNlKGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgID0gbigpKSkgJT4lIA0KICAgIHJlbmFtZSgiRXN0aW1hdGVkIHBlY2sgcmF0ZSIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICJJbmRpY2F0ZWQgZXhwZWN0YXRpb24iID0gRXhwZWN0YXRpb24pICU+JSANCiAgYmluZF9yb3dzKGZpdHRlZChiYXNlbGluZV9wZWNrX21vZGVsX3ppLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgICAgIGFzX3RpYmJsZSgpICU+JQ0KICAgICAgICAgICAgICBkaXN0aW5jdChFc3RpbWF0ZSwgLmtlZXBfYWxsID0gVCkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSAlPiUgDQogICAgICAgICAgICAgIHJlbmFtZSgiRXN0aW1hdGVkIHBlY2sgcmF0ZSIgPSBFc3RpbWF0ZSkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYEluZGljYXRlZCBleHBlY3RhdGlvbmAgPSAiQmFzZWxpbmUiLCBHZW5kZXIgPSAiLSIpICU+JSANCiAgICAgICAgICAgICAgYmluZF9jb2xzKGJhc2VsaW5lX2RhdGEgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0aW5jdChQaWdlb25fSUQpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgID0gbGVuZ3RoKFBpZ2Vvbl9JRCkpKSkgJT4lIA0KICBzZWxlY3QoYEluZGljYXRlZCBleHBlY3RhdGlvbmAsIGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgLCBldmVyeXRoaW5nKCkpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQpgYGANCg0KDQokfiQNCg0KIyMjIEJ1aWxkIEZpZ3VyZSAyZS1oDQoNCiR+JA0KDQoqKkdldCBwb3N0ZXJpb3IgbWVhbnMgYW5kIGRpZmZlcmVuY2UgY29udHJhc3RzKioNCg0KYGBge3J9DQoNCiMgdHJlYXRtZW50IG1vZGVsDQoNCnBlY2tfZHJhd3NfdHJlYXRtZW50IDwtDQogIGFzX2RyYXdzX2RmKHBlY2tfbW9kZWxfdHJlYXRtZW50KSAlPiUgDQogIG11dGF0ZShIdW5ncnkgPSBleHAoYl9CaWFzX3RyZWF0bWVudEh1bmdyeSksDQogICAgICAgICBTYXRpYXRlZCA9IGV4cChiX0JpYXNfdHJlYXRtZW50U2F0aWF0ZWQpLA0KICAgICAgICAgZGlmZl9jb250cmFzdCA9IChIdW5ncnkgLSBTYXRpYXRlZCkpICU+JSANCiAgc2VsZWN0KEh1bmdyeSwgU2F0aWF0ZWQsIGRpZmZfY29udHJhc3QpICU+JQ0KICBiaW5kX2NvbHMoYmFzZWxpbmVfcGVja19wcmVkaWN0aW9ucyAlPiUgc2VsZWN0KEJhc2VsaW5lX2VzdGltYXRlKSkgJT4lIA0KICBwaXZvdF9sb25nZXIobmFtZXNfdG8gPSAiVHJlYXRtZW50IiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIsIGNvbHMgPSAxOjMpICU+JSANCiAgbXV0YXRlKFByZWRpY3RvciA9ICJBbGxvY2F0ZWQgcHJpbWVyIikNCg0KDQpwNiA8LSANCiAgICBwZWNrX2RyYXdzX3RyZWF0bWVudCAlPiUgDQogICAgZmlsdGVyKFRyZWF0bWVudCAhPSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgICBnZ3Bsb3QoYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArDQogICAgc3RhdF9zbGFiKGFlcyh5ID0gQmFzZWxpbmVfZXN0aW1hdGUpLA0KICAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuOCwgc2xhYl9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIikgKw0KICAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSkgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDIpKSArDQogICAgY29vcmRfZmxpcCh5bGltID0gYygwLCAyMCkpICsNCiAgICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgICB4bGFiKCJBbGxvY2F0ZWQgcHJpbWVyIikgKw0KICAgIHlsYWIoIkVzdGltYXRlZCBwZWNrcyBwZXIgbWluIikgKw0KICAgIHRoZW1lX2J3KCkgKyANCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQoNCnA3IDwtDQogIHBlY2tfZHJhd3NfdHJlYXRtZW50ICU+JSANCiAgZmlsdGVyKFRyZWF0bWVudCA9PSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LCBzY2FsZSA9MC41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzRdKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoLTUsIDEyKSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuNzUpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYihOVUxMKSArDQogIHlsYWIoIkh1bmdyeSAtIFNhdGlhdGVkIGRpZmZlcmVuY2VcbmNvbnRyYXN0IChwZWNrcyBwZXIgbWluKSIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQ0KDQojIGV4cGVjdGF0aW9uIG1vZGVsDQoNCnBlY2tfZHJhd3NfZXhwZWN0YXRpb24gPC0NCiAgYXNfZHJhd3NfZGYocGVja19tb2RlbF9leHBlY3RhdGlvbikgJT4lIA0KICBtdXRhdGUoSHVuZ3J5ID0gZXhwKGJfRXhwZWN0YXRpb25IdW5ncnkpLA0KICAgICAgICAgU2F0aWF0ZWQgPSBleHAoYl9FeHBlY3RhdGlvblNhdGlhdGVkKSwNCiAgICAgICAgIGRpZmZfY29udHJhc3QgPSAoSHVuZ3J5IC0gU2F0aWF0ZWQpKSAlPiUgDQogIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkLCBkaWZmX2NvbnRyYXN0KSAlPiUgDQogIGJpbmRfY29scyhiYXNlbGluZV9wZWNrX3ByZWRpY3Rpb25zICU+JSBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUpKSAlPiUgDQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJUcmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiUG9zdGVyaW9yX2VzdGltYXRlIiwgY29scyA9IDE6MykgJT4lIA0KICBtdXRhdGUoUHJlZGljdG9yID0gIkFsbG9jYXRlZCBwcmltZXIiKQ0KDQpwOCA8LQ0KICBwZWNrX2RyYXdzX2V4cGVjdGF0aW9uICU+JSANCiAgZmlsdGVyKFRyZWF0bWVudCAhPSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gVHJlYXRtZW50LCB5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgc3RhdF9zbGFiKGFlcyh5ID0gQmFzZWxpbmVfZXN0aW1hdGUpLA0KICAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuOCwgc2xhYl9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIikgKw0KICAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDIpKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMjApKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYigiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIikgKw0KICB5bGFiKCJFc3RpbWF0ZWQgcGVja3MgcGVyIG1pbiIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCg0KcDkgPC0NCiAgcGVja19kcmF3c19leHBlY3RhdGlvbiAlPiUgDQogIGZpbHRlcihUcmVhdG1lbnQgPT0gImRpZmZfY29udHJhc3QiKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwgc2NhbGUgPTAuNSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVs0XSkgKw0KICBjb29yZF9mbGlwKHlsaW0gPSBjKC01LCAxMikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjc1KSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoTlVMTCkgKw0KICB5bGFiKCJIdW5ncnkgLSBTYXRpYXRlZCBkaWZmZXJlbmNlXG5jb250cmFzdCAocGVja3MgcGVyIG1pbikiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCmBgYA0KDQpOb3cgZm9yIHRoZSBnZW5kZXIgbW9kZWxzDQoNCmBgYHtyfQ0KIyB3aXRoIGdlbmRlcg0KDQpnZW5kZXJfdHJlYXRtZW50X2RyYXdzXzIgPC0NCiAgZml0dGVkKHBlY2tfbW9kZWxfdHJlYXRtZW50X2dlbmRlciwgDQogICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGFfZ2VuZGVyLCBzdW1tYXJ5ID0gRiwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogIGFzX3RpYmJsZSgpICU+JSANCiAgcmVuYW1lKEh1bmdyeV9Xb21lbiA9IFYxLCBIdW5ncnlfTWVuID0gVjIsIFNhdGlhdGVkX1dvbWVuID0gVjMsIFNhdGlhdGVkX01lbiA9IFY0KSAlPiUgDQogIGJpbmRfY29scyhiYXNlbGluZV9wZWNrX3ByZWRpY3Rpb25zICU+JSBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUpKSAlPiUgDQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJHcm91cCIsIHZhbHVlc190byA9ICJQb3N0ZXJpb3JfZXN0aW1hdGUiLCBjb2xzID0gMTo0KSAlPiUgDQogIHNlcGFyYXRlKHNlcCA9ICJfIiwgY29sID0gR3JvdXAsIGludG8gPSBjKCJUcmVhdG1lbnQiLCAiR2VuZGVyIikpDQogIA0KY2FsY3VsYXRlX2FsbF90aGVfZGlmZnNfMyA8LQ0KICBmaXR0ZWQocGVja19tb2RlbF90cmVhdG1lbnRfZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXIsIHN1bW1hcnkgPSBGLCByZV9mb3JtdWxhID0gTkEpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgbXV0YXRlKFdvbWVuX2hfc19kaWZmID0gSHVuZ3J5X1dvbWVuIC0gU2F0aWF0ZWRfV29tZW4sDQogICAgICAgICBNZW5faF9zX2RpZmYgPSBIdW5ncnlfTWVuIC0gU2F0aWF0ZWRfTWVuLA0KICAgICAgICAgZGlmZl9kaWZmID0gV29tZW5faF9zX2RpZmYgLSBNZW5faF9zX2RpZmYpICU+JSANCiAgc2VsZWN0KGNvbnRhaW5zKCJkaWZmIikpICU+JQ0KICByZW5hbWUoYEgtUyAod29tZW4pYCA9IFdvbWVuX2hfc19kaWZmLA0KICAgICAgICAgYEgtUyAobWVuKWAgPSBNZW5faF9zX2RpZmYsDQogICAgICAgICBgSW50ZXJhY3Rpb25gID0gZGlmZl9kaWZmKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gMTozLCBuYW1lc190byA9ICJkaWZmX2NvbnRyYXN0IiwgdmFsdWVzX3RvID0gInBvc3Rlcmlvcl9kaWZmIikNCg0KZ3A1IDwtIA0KICBnZW5kZXJfdHJlYXRtZW50X2RyYXdzXzIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBHZW5kZXIsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgIHN0YXRfc2xhYihhbHBoYSA9IDAuOCwgc2hhcGUgPSAyMSwgYWVzKGZpbGwgPSBUcmVhdG1lbnQpKSArDQogIHN0YXRfc2xhYihhZXMoeSA9IEJhc2VsaW5lX2VzdGltYXRlKSwNCiAgICAgICAgICAgICAgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjgsIHNsYWJfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIpICsNCiAgI3N0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICMgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICMgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LA0KICAgIyAgICAgICAgICAgIGZpbGwgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KVsyXSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDEwKVs0XSwgbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzZdKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLCAwLCAxKSkgKw0KICBsYWJzKHggPSAiR2VuZGVyIiwgeSA9ICJFc3RpbWF0ZWQgcGVja3MgcGVyIG1pbiIsIGZpbGwgPSAiQWxsb2NhdGVkXG5QcmltZXIiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkNCg0KDQoNCmdwNiA8LQ0KICBjYWxjdWxhdGVfYWxsX3RoZV9kaWZmc18zICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl9jb250cmFzdCwgeSA9IHBvc3Rlcmlvcl9kaWZmKSkgKyANCiAgICAjc3RhdF9zbGFiKGFscGhhID0gMC45LCBzaGFwZSA9IDIxLCBhZXMoZmlsbCA9IEdlbmRlcikpICsNCiAgc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41LA0KICAgICAgICAgICAgICAgZmlsbCA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDEwKVs1XSkgKw0KICAjc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuNzUpICsNCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTAsIDE1KSkgKw0KICB4bGFiKCJEaWZmZXJlbmNlIGNvbnRyYXN0IikgKw0KICB5bGFiKCJQZWNrcyBwZXIgbWluIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQoNCiMgZXhwZWN0YXRpb24gbW9kZWwNCg0KZ2VuZGVyX2V4cGVjdGF0aW9uX2RyYXdzXzIgPC0NCiAgZml0dGVkKHBlY2tfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IEYsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tZW4gPSBWMSwgSHVuZ3J5X01lbiA9IFYyLCBTYXRpYXRlZF9Xb21lbiA9IFYzLCBTYXRpYXRlZF9NZW4gPSBWNCkgJT4lIA0KICBiaW5kX2NvbHMoYmFzZWxpbmVfcGVja19wcmVkaWN0aW9ucyAlPiUgc2VsZWN0KEJhc2VsaW5lX2VzdGltYXRlKSkgJT4lIA0KICBwaXZvdF9sb25nZXIobmFtZXNfdG8gPSAiR3JvdXAiLCB2YWx1ZXNfdG8gPSAiUG9zdGVyaW9yX2VzdGltYXRlIiwgY29scyA9IDE6NCkgJT4lIA0KICBzZXBhcmF0ZShzZXAgPSAiXyIsIGNvbCA9IEdyb3VwLCBpbnRvID0gYygiVHJlYXRtZW50IiwgIkdlbmRlciIpKQ0KICANCmNhbGN1bGF0ZV9hbGxfdGhlX2RpZmZzXzQgPC0NCiAgZml0dGVkKHBlY2tfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IEYsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tZW4gPSBWMSwgSHVuZ3J5X01lbiA9IFYyLCBTYXRpYXRlZF9Xb21lbiA9IFYzLCBTYXRpYXRlZF9NZW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tZW5faF9zX2RpZmYgPSBIdW5ncnlfV29tZW4gLSBTYXRpYXRlZF9Xb21lbiwNCiAgICAgICAgIE1lbl9oX3NfZGlmZiA9IEh1bmdyeV9NZW4gLSBTYXRpYXRlZF9NZW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21lbl9oX3NfZGlmZiAtIE1lbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tZW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1lbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKQ0KDQpncDcgPC0gDQogIGdlbmRlcl9leHBlY3RhdGlvbl9kcmF3c18yICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gR2VuZGVyLCB5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgICBzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gVHJlYXRtZW50KSkgKw0KICBzdGF0X3NsYWIoYWVzKHkgPSBCYXNlbGluZV9lc3RpbWF0ZSksDQogICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC44LCBzbGFiX2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siKSArDQogICNzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAjICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAjICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwNCiAgICMgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSlbMl0pICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgbGFicyh4ID0gIkdlbmRlciIsIHkgPSAiRXN0aW1hdGVkIHBlY2tzIHBlciBtaW4iLCBmaWxsID0gIkluZGljYXRlZFxuZXhwZWN0YXRpb24iKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpDQoNCg0KDQpncDggPC0NCiAgY2FsY3VsYXRlX2FsbF90aGVfZGlmZnNfNCAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRpZmZfY29udHJhc3QsIHkgPSBwb3N0ZXJpb3JfZGlmZikpICsgDQogICAgI3N0YXRfc2xhYihhbHBoYSA9IDAuOSwgc2hhcGUgPSAyMSwgYWVzKGZpbGwgPSBHZW5kZXIpKSArDQogIHN0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDMsIHN0cm9rZSA9IDEuNSwNCiAgICAgICAgICAgICAgIGZpbGwgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAxMClbNV0pICsNCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDIpKSArDQogIGNvb3JkX2ZsaXAoKSsjeWxpbSA9IGMoMjUsIDU1KSkgKw0KICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjc1KSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEwLCAxNSkpICsNCiAgeGxhYigiRGlmZmVyZW5jZSBjb250cmFzdCIpICsNCiAgeWxhYigiUGVja3MgcGVyIG1pbiIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkNCmBgYA0KDQoNCiR+JA0KDQojIyMgRmluZCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGJhc2VsaW5lIGFuZCBvYnNlcnZlciBlc3RpbWF0ZXMNCg0KKipUYWJsZSBTNSoqLiBUaGUgZGVncmVlIHRvIHdoaWNoIGVhY2ggZ3JvdXAgb2Ygb2JzZXJ2ZXIncyBvdmVyZXN0aW1hdGVzIGZlZWRpbmcgcmF0ZSAobnVtYmVyIG9mIGdyb3VuZCBwZWNrcyBwZXIgbWludXRlKQ0KDQpgYGB7cn0NCmJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgJT4lIHNlbGVjdChCYXNlbGluZV9lc3RpbWF0ZSkgJT4lICBiaW5kX2NvbHMoDQogIA0KICBhc19kcmF3c19kZihwZWNrX21vZGVsX3RyZWF0bWVudCkgJT4lIA0KICAgIG11dGF0ZShIdW5ncnkgPSBleHAoYl9CaWFzX3RyZWF0bWVudEh1bmdyeSksDQogICAgICAgICAgIFNhdGlhdGVkID0gZXhwKGJfQmlhc190cmVhdG1lbnRTYXRpYXRlZCkpICU+JSANCiAgICBzZWxlY3QoSHVuZ3J5LCBTYXRpYXRlZCkpICU+JSANCiAgbXV0YXRlKGBCaWFzIHRyZWF0bWVudCBTYXRpYXRlZCAvIEJhc2VsaW5lYCA9IFNhdGlhdGVkIC8gQmFzZWxpbmVfZXN0aW1hdGUsDQogICAgICAgICBgQmlhcyB0cmVhdG1lbnQgSHVuZ3J5IC8gQmFzZWxpbmVgID0gSHVuZ3J5IC8gQmFzZWxpbmVfZXN0aW1hdGUpICU+JSANCiAgc2VsZWN0KGNvbnRhaW5zKCJCaWFzIikpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIHZhbHVlc190byA9ICJlc3RpbWF0ZSIsIG5hbWVzX3RvID0gIlN0YXQiKSAlPiUgDQogIGdyb3VwX2J5KFN0YXQpICU+JSANCiAgc3VtbWFyaXNlX2RyYXdzKCJtZWRpYW4iLCAic2QiLCB+cXVhbnRpbGUoLngsIHByb2JzID0gYygwLjAyNSwgMC45NzUpLCBuYS5ybSA9IFRSVUUpLCAuY29yZXMgPSA0KSAlPiUgDQogIHNlbGVjdCgtdmFyaWFibGUpICU+JSANCiAgDQogIGJpbmRfcm93cygNCiAgICANCiAgICBiYXNlbGluZV9wZWNrX3ByZWRpY3Rpb25zICU+JSBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUpICU+JSAgYmluZF9jb2xzKA0KICAgICAgDQogICAgICBhc19kcmF3c19kZihwZWNrX21vZGVsX2V4cGVjdGF0aW9uKSAlPiUgDQogICAgICAgIG11dGF0ZShIdW5ncnkgPSBleHAoYl9FeHBlY3RhdGlvbkh1bmdyeSksDQogICAgICAgICAgICAgICBTYXRpYXRlZCA9IGV4cChiX0V4cGVjdGF0aW9uU2F0aWF0ZWQpKSAlPiUgDQogICAgICAgIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkKSkgJT4lIA0KICAgICAgbXV0YXRlKGBFeHBlY3RhdGlvbiBTYXRpYXRlZCAvIEJhc2VsaW5lYCA9IFNhdGlhdGVkIC8gQmFzZWxpbmVfZXN0aW1hdGUsDQogICAgICAgICAgICAgYEV4cGVjdGF0aW9uIEh1bmdyeSAvIEJhc2VsaW5lYCA9IEh1bmdyeSAvIEJhc2VsaW5lX2VzdGltYXRlKSAlPiUgDQogICAgICBzZWxlY3QoY29udGFpbnMoIkV4cGVjdGF0aW9uIikpICU+JSANCiAgICAgIHBpdm90X2xvbmdlcihjb2xzID0gZXZlcnl0aGluZygpLCB2YWx1ZXNfdG8gPSAiZXN0aW1hdGUiLCBuYW1lc190byA9ICJTdGF0IikgJT4lIA0KICAgICAgZ3JvdXBfYnkoU3RhdCkgJT4lIA0KICAgICAgc3VtbWFyaXNlX2RyYXdzKCJtZWRpYW4iLCAic2QiLCB+cXVhbnRpbGUoLngsIHByb2JzID0gYygwLjAyNSwgMC45NzUpLCBuYS5ybSA9IFRSVUUpLCAuY29yZXMgPSA0KSAlPiUgDQogICAgICBzZWxlY3QoLXZhcmlhYmxlKQ0KICApICU+JSANCiAgcGFuZGVyKCkNCmBgYA0KDQoNCiMgRmlndXJlIDINCg0KT3B0aW9uIDENCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIHdpZHRoID0gMTB9DQoocDIgKyBwMykgLyAocDQgKyBwNSkgLyAocDYgKyBwNykgLyAocDggKyBwOSkgKw0KICAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpDQpgYGANCg0KT3B0aW9uIDINCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIHdpZHRoID0gMTB9DQooZ3AxICsgZ3AyKSAvIChncDMgKyBncDQpIC8gKGdwNSArIGdwNikgLyAoZ3A3ICsgZ3A4KSArDQogICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykNCmBgYA0KDQoqKkZpZ3VyZSAyKiouIFBvc3RlcmlvciBtZWFuIGVzdGltYXRlcyBhbmQgZGlmZmVyZW5jZSBjb250cmFzdHMgZm9yIG9ic2VydmVyIGVzdGltYXRlZCBncm91cCBmb3JhZ2luZyBwZXJjZW50YWdlIGFuZCBpbmRpdmlkdWFsIGZlZWRpbmcgcmF0ZXMuIFRoZSBjb2xvdXJlZCBhcmVhIGlzIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGFuZCB0aGUgd2hpdGUgcG9pbnQgaXMgdGhlIG1lYW4gZXN0aW1hdGUgd2l0aCBhc3NvY2lhdGVkIDY3JSBhbmQgOTUlIGNyZWRpYmxlIGludGVydmFscy4NCg0KDQojIFNlc3Npb24gaW5mbw0KDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkgJT4lIHBhbmRlcg0KYGBgDQoNCg==